[英]Limiting number of each item in knapsack solution
我试图更好地理解背包问题,并查看此处提供的“特定动态编程解决方案”: http : //rosettacode.org/wiki/Knapsack_Problem/Python
我想对其进行修改,以便解决方案中最多可以使用项目中的每个项目。 我认为可以通过遍历重量和体积以外的项目来完成此操作,但这没有用。
任何帮助表示赞赏。
编辑:示例:当前代码定义一个项目列表
items = [Bounty('panacea', 3000, 3, 25),
Bounty('ichor', 1800, 2, 15),
Bounty('gold', 2500, 20, 2)]
它选择的最大项目组合值小于背包的重量和体积限制,并且允许每个项目多次使用。
我希望它选择重量和值<背包的重量和体积限制的物品的最大值组合,但是要限制物品中的每个物品最多只能使用一次。
正如我在评论中提到的那样,您可以使用O(n * W)
动态编程方法,其中n
是项目数, W
是背包的容量。 有关更多详细信息,请参阅此处:
https://zh.wikipedia.org/wiki/背包的问题#0.2F1_背包的问题
如果仅W
足够小,该算法非常容易实现,并且速度非常快。
如果要防止每个项目多次使用:
这样,每个项目就不能被多次计数。
通过首先遍历项目,您不会失去项目组合的机会。
作为一个示例,当您的表为空并且您处理第一个项目时。 它将利用当前的最佳值和位置[w-weight][v-volume]+value
table[w][v] = max(table[w][v], table[w - item.weight][v - item.volume] + item.value)
所以对于灵丹妙药 :
当您按升序排列时,处理table[50][6]
时table[25][3]
将为3000
。 使其达到6000,使用2次。
当您按降序排列时,处理table[50][6]
时table[25][3]
仍为0
。 使其达到3000,仅使用一次。
因此,无论较低的表值是什么,它都不会来自同一项目。
顺便说一句,当所有物品都适合背包时,这确实崩溃了。
您可以重写此代码,也可以简单地在方法开始处添加一个检查:
def knapsack_dp(items, sack):
if(sum(item.weight for item in items) <= sack.weight
and sum(item.volume for item in items) <= sack.volume):
return [1] * len(items)
完全适合时,请退回所有物品。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.