0/1背包澄清和优化

时间:2013-05-17 22:30:45

标签: algorithm knapsack-problem

我正在阅读关于0-1背包问题的维基百科。我只想澄清一些事情。我有两个问题: http://en.wikipedia.org/wiki/Knapsack_problem#0.2F1_Knapsack_Problem

我遇到了这个伪代码:

// Input:
// Values (stored in array v)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)
for w from 0 to W do
  m[0, w] := 0
end for 
for i from 1 to n do
  for j from 0 to W do
    if j >= w[i] then
      m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])
    else
      m[i, j] := m[i-1, j]
    end if
  end for
end for

特别针对这部分:

    if j >= w[i] then
      m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])

1)如果我错了,请纠正我,但不应该是:

      m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i], m[i,j-w[i]] + v[i])

如果没有,有人可以解释为什么不需要它吗?

...

2)我还有另一个问题,如果说我想稍微优化一下。通过GCD对项目的所有权重(即存储在数组w中的值的GCD)增加循环“对于j从0到W”的循环是否明智。 (当我即将实现它时,我现在正在考虑代码方式)。

1 个答案:

答案 0 :(得分:1)

1)当你添加m[i,j-w[i]] + v[i]时,你允许多次选择相同的项目i,因此它不再是0/1背包 - 它变成了无限制的背包问题每件物品的数量。

2)是的,但是这个GCD在实际情况下通常会降到1,因此对于一般情况不值得打扰,除非您事先知道您的数据会从中受益。 (在这种情况下,你实际上想要通过GCD划分所有数据,并保持原始算法一次递增1,然后将最终结果乘以GCD。这样可以节省你的内存,但你的背包容量也必须被这样的GCD整除)