在维基百科中,背包的算法如下:
for i from 1 to n do
for j from 0 to W do
if j >= w[i] then
T[i, j] := max(T[i-1, j], T[i-1, j-w[i]] + v[i]) [18]
else
T[i, j] := T[i-1, j]
end if
end for
end for
我在网上找到的所有例子都是相同的结构 我无法理解的是,这段代码如何考虑到最大值可能来自较小背包?例如。如果背包容量为8,则最大值可能来自容量7(8-1) 我找不到任何逻辑可以考虑,也许最大值来自较小的背包。这是错误的想法吗?
答案 0 :(得分:4)
背包的动态编程解决方案基本上是递归的:
T(i,j) = max{ T(i-1,j) , T(i-1,j-w[i]) + v[i] }
// ^ ^
// ignore the element add the element, your value is increase
// by v[i] and the additional weight you can
// carry is decreased by w[i]
(如果为每个T(i,j) = -infinity
设置j < 0
,则其他条件在递归形式中是多余的。
这个想法是详尽的搜索,你从一个元素开始,你有两种可能性:添加它,或者不要。
您检查两个选项,并选择其中最好的选项。
由于它以递归方式完成 - 您有效地检查所有可能性以将元素分配给背包。
请注意,维基百科中的解决方案基本上是针对相同递归公式的自下而上的解决方案
答案 1 :(得分:3)
如我所见,你误解了背包的概念。我将在这里详细描述,直到我们到达代码部分。
首先,问题有两个版本:
//and this one is the one yo are facing problems with
对于第一个问题,您可以理解如下:
给出最大容量 W 的背包,以及由 n 项组成的 S 组 每个项目 i 都有一些权重 wi 和受益值 bi (所有 wi 和 W 是整数值。)
那么,如何打包背包以达到最大的包装总价值 项目
在数学口中:
并使用动态编程解决此问题我们为每个可用项设置了一个表V[0..k, 0..W]
,每个权重的一列 0 到 W 。
我们需要仔细识别子问题,
子问题然后将计算V[k,w]
,即找到最佳解决方案
Sk= {items labeled 1, 2, .. k}
在尺寸 w 的背包中(给定容量 w 且项目 1,...,k 可实现的最大值)
所以,我们发现这个公式可以解决我们的问题:
此算法仅查找可以在背包中携带的最大可能值 即,V [n,W]中的值 要知道产生此最大值的项目,这将是另一个主题。
我真的希望这个答案会对你有所帮助。我有一个pp演示文稿,随你一起填写表格,并逐步向您展示算法。但我不知道如何将其上传到stackoverflow。如果需要任何帮助,请告诉我。