我查看了许多资源以及this问题,但我仍然困惑为什么我们需要动态编程来解决0/1背包?
问题是:我有N
个项目,每个项目的值为Vi
,每个项目的权重为Wi
。我们有一个总重量为W
的袋子。如何选择项目以获得超过重量限制的最佳总值。
我对动态编程方法感到困惑:为什么不计算每个项目的(值/重量)分数,并选择具有最小分数的项目,其重量小于袋子中的剩余重量?
答案 0 :(得分:3)
对于基于分数的方法,您可以轻松找到反例。
考虑
W=[3, 3, 5]
V=[4, 4, 7]
Wmax=6
您的方法提供了最佳价值Vopt=7
(我们从7/5 > 4/3
开始采用最后一项),但是前两项会给我们Vopt=8
。
答案 1 :(得分:2)
正如其他答案所指出的,你的方法存在边缘情况。
为了更好地解释递归解决方案,也许更好地理解它,我建议你用这个推理来解决它:
对于每个“子包”
此算法有效,因为它跨越拟合元素的所有可能组合,并找到具有最高值的组合。
相反,直接解决方案不可能是the problem is NP-hard。
答案 2 :(得分:1)
看看这个反例:
Weight 7, W/V pairs (3/10),(4/12),(5/21)
答案 3 :(得分:1)
当存在单位比例时,贪婪算法失败。例如,请考虑以下示例:
n = 1 2,P = 4 18,W = 2 18,P / W = 2 1
背包容量= 18
根据贪婪算法,它将考虑第一项,因为它的P / W比率更大,因此总利润将是4(因为它不能在第一项之后插入第二项,因为容量减少到16之后插入第一项)。
但实际答案是18。
因此,有多个极端情况,贪婪无法提供最佳解决方案,这就是我们在0/1背包问题中使用动态编程的原因。