繁体   English   中英

背包解决方案中每个项目的限制数量

[英]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足够小,该算法非常容易实现,并且速度非常快。

如果要防止每个项目多次使用:

1)使DP算法减少而不是先增加+对每个项目进行处理,而不是首先遍历weigth和体积

这样,每个项目就不能被多次计数。

通过首先遍历项目,您不会失去项目组合的机会。

作为一个示例,当您的表为空并且您处理第一个项目时。 它将利用当前的最佳值和位置[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,仅使用一次。

因此,无论较低的表值是什么,它都不会来自同一项目。

2)检查所有物品是否都适合背包

顺便说一句,当所有物品都适合背包时,这确实崩溃了。

您可以重写此代码,也可以简单地在方法开始处添加一个检查:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM