knapsack背包问题python实现

1,问题描述
不同重量的物品对应的价值不同,对一个容量固定的背包来说,如何用背包装这些物品使得背包所装物品的总价值最高。

2,参数定义
背包的容量为:C(capacity);
物品编号i对应的重量是:weight[i];
物品编号i对应的价值是:value[i]。

3,解题思路
3.1,
我们最终要求的是背包所装物品的最高价值,则设最高价值为F;其总价值F是由包的容量(C)和所装的i个物品共同决定的,因此我们设价值F与背包容量C、i个物品的大小共同决定的,则设其函数对应关系为F(i,C),其意义为使用i个物件充分填充空间C得到
的最大价值。

3.2,
若我们现在已知前i-1个物品填充容量为C的背包得到的最大价值是F(i-1,C),现在考虑再放一个物品i到背包中,会出现以下2种情况:
1),剩余容量太小,放不下物品i;
如果放不下物品i,则表示前i个物品填充背包与前i-1个物品填充背包所得到的最高价值是一样的,即:
F(i,C) = F(i-1,C)
2),剩余容量足够,可以放下物品i。
如果能放下物品i,则表示前i个物品填充背包与前i-1个物品填充背包所得到的最高值是不一样的,一定有个剩余容量能装下物品i的重量weight[i],即前i-1个物品填充容量C-weight[i],第i个物品填充剩余容量weight[i],即前i个物品填充背
包容量为C得到的总价值为前i-1个物品填充容量为C-weight[i]的背包,加上第i个物品填充剩余容量weight[i],
F(i,C) = F(i-1,C-weight[i]) + value[i]
对于上述两种情况而言,不论放第i个物品还是不放,只用取其总价值的最大值即可,即:
F(i,C) = max(F(i-1,C), F(i-1,C-weight[i]) + value[i]) --式1

3.3,
得到上述函数表达式后,接下来需要确定边界值,背包容量C或前i个物品这2个变量中有一个为0则其总价值均为0,即:
F(0,C) = 0;
F(i,0) = 0;
F(0,0) = 0.
即:
F(i,C) = 0 if i == 0 or C == 0 --式2

3.4,最后根据式1和式2得到:
F(i,C) = {
1),0 (while i == 0)
2),0 (while C == 0)
3),max(F(i-1,C), F(i-1,C-weight[i]) + value[i]) (while 当前的容量C >= 第i个物品的重量weight[i])
}

4,注意点:
1,弄清函数概念。
2,边界值确定。


5,示例代码
写代码的过程中可以在Excel写个例子,对照着写

 1 def knapsack(weight, value, capacity):
 2     if len(weight) == 0 or len(value) == 0 or capacity == 0:
 3         return -1
 4     else:
 5         totalValue = [[0 for i in range(capacity + 1)] for j in range(len(value) + 1)]
 6         for ithGood in range(1, len(value) + 1):  # 1--4
 7             for currentCapacity in range(1, capacity + 1):  # 1--5
 8                 if currentCapacity >= weight[ithGood-1]:
 9                     totalValue[ithGood][currentCapacity] = max(totalValue[ithGood - 1][currentCapacity],
10                                                      totalValue[ithGood - 1][currentCapacity - weight[ithGood-1]]
11                                                      + value[ithGood-1])
12                 else:
13                     totalValue[ithGood][currentCapacity] = totalValue[ithGood - 1][currentCapacity]
14         return totalValue[-1][-1]
15 
16 
17 if __name__ == '__main__':
18     weightTest = [4, 5, 2, 1, 6]  # [2, 2, 6, 5, 4]
19     valueTest = [4500, 5700, 2250, 1100, 6700]  # [6, 3, 5, 4, 6]
20     capacityTest = 8  # 10
21     print(knapsack(weightTest, valueTest, capacityTest))

6,参考文献

https://www.cnblogs.com/coded-ream/p/7208019.html

https://www.cnblogs.com/bugxch/p/13830904.html

posted @ 2021-12-13 19:47  puppet洛洛  阅读(180)  评论(0编辑  收藏  举报