python 实现knapsack背包问题算法

knapsack背包问题算法介绍

Knapsack背包问题是一种常见的动态规划问题,旨在求解在给定的重量限制下,如何选择一组物品使得它们的总价值最大化。背包问题有多种变体,其中最常见的是01背包问题和完全背包问题。以下是这两种背包问题的算法概述:

1. 01背包问题

在01背包问题中,每个物品只有一个,可以选择放入背包或不放入背包。解决01背包问题通常使用动态规划算法。

算法步骤:

状态定义:设dpij表示在前i个物品中,选择若干物品放入容量为j的背包时,能得到的最大价值。

状态转移方程:

如果不选第i个物品,则 d p i j = d p i − 1 j dpij = dpi-1j dpij=dpi−1j

如果选第i个物品,则 d p i j = d p i − 1 j − w e i g h t s \[ i ] + v a l u e s i dpij = dpi-1j-weights\[i] + valuesi dpij=dpi−1j−weights\[i]+valuesi(前提是 j > = w e i g h t s i j >= weightsi j>=weightsi,即背包容量足够)。

因此,状态转移方程为: d p i j = m a x ( d p i − 1 j , d p i − 1 j − w e i g h t s \[ i ] + v a l u e s i ) dpij = max(dpi-1j, dpi-1j-weights\[i] + valuesi) dpij=max(dpi−1j,dpi−1j−weights\[i]+valuesi)。

初始化: d p 0 j = 0 dp0j = 0 dp0j=0(没有物品时,背包价值为0),对于所有的j。

结果: d p n c dpnc dpnc即为所求的最大价值,其中n是物品数量,c是背包容量。

2. 完全背包问题

在完全背包问题中,每种物品都有无限个,可以选择放入背包中的任意数量(只要不超过背包容量)。

算法步骤:

状态定义:与01背包相同,设dpij表示在前i个物品中,选择若干物品放入容量为j的背包时,能得到的最大价值。

状态转移方程:

对于完全背包问题,由于物品可以无限选择,所以状态转移方程略有不同: d p i j = m a x ( d p i − 1 j , d p i j − w e i g h t s \[ i ] + v a l u e s i ) dpij = max(dpi-1j, dpij-weights\[i] + valuesi) dpij=max(dpi−1j,dpij−weights\[i]+valuesi)(注意这里是 d p i j − w e i g h t s \[ i ] dpij-weights\[i] dpij−weights\[i]而不是 d p i − 1 j − w e i g h t s \[ i ] ) dpi-1j-weights\[i]) dpi−1j−weights\[i])。

初始化和结果与01背包相同。

注意

对于空间优化,背包问题常使用滚动数组来减少空间复杂度,即将二维数组dpij优化为一维数组dpj,并调整遍历顺序以避免覆盖未计算的状态。

背包问题是组合优化的经典问题之一,也是NP完全问题的一种。对于大规模数据,可能需要采用更高效的算法或启发式方法来求解。

knapsack背包问题算法python实现样例

以下是一个Python实现的knapsack背包问题算法:

python 复制代码
def knapsack(values, weights, capacity):
    # 创建一个二维数组,用于存储每个子问题的最优解
    dp = [[0] * (capacity + 1) for _ in range(len(values) + 1)]

    # 填充二维数组,计算每个子问题的最优解
    for i in range(1, len(values) + 1):
        for j in range(1, capacity + 1):
            # 如果当前物品的重量大于背包容量,则不能放入背包,继承上一个子问题的最优解
            if weights[i - 1] > j:
                dp[i][j] = dp[i - 1][j]
            else:
                # 如果可以放入背包,选择放入物品或不放入物品的最大值
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])

    # 返回最终的最优解
    return dp[len(values)][capacity]

# 测试
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
print(knapsack(values, weights, capacity))

上述代码中, values 列表存储每个物品的价值, weights 列表存储每个物品的重量, capacity 表示背包的容量。 knapsack 函数使用动态规划的方法解决了knapsack背包问题。它创建了一个二维数组 dp,并且通过遍历每个子问题的范围来填充数组。最后,返回最终的最优解。在上述测试中,输出结果为220,表示背包可以装入价值为220的物品。

相关推荐
多加点辣也没关系8 分钟前
JavaScript|第30章:事件机制
开发语言·javascript
小大宇9 分钟前
python milvus 案例
开发语言·python·milvus
Gauss松鼠会20 分钟前
【GaussDB】GaussDB锁阻塞源头查询
java·开发语言·前端·数据库·算法·gaussdb·经验总结
oier_Asad.Chen22 分钟前
【洛谷题解/AcWing题解】洛谷P4011 孤岛营救问题/AcWing1131拯救大兵瑞恩
数据结构·笔记·学习·算法·动态规划·图论·宽度优先
mingo_敏36 分钟前
DeepAgents : 后端(Backends)
java·开发语言
mabing9931 小时前
Qt QMessageBox、QDialogButtonBox中英文翻译动态切换
开发语言·qt
BerryS3N1 小时前
Java 后端转型大模型:Demo 能跑不等于能上线
java·人工智能·python·java后端·spring ai·langchain4j·大模型转型
Sagittarius_A*1 小时前
【RCELABS】Level 17~18 —— PHP命令执行函数与环境变量注入
开发语言·安全·web安全·靶场·php·rce
冻柠檬飞冰走茶1 小时前
PTA基础编程题目集 7-19 支票面额(C语言实现)
c语言·开发语言·数据结构·算法
制造数据与AI践行者老蒋1 小时前
智联工坊实战:从“金鱼记忆”到“记住了”:给制造Agent装上记忆芯片的完整指南
人工智能·python·langchain·制造