有界背包特殊情况 - 小物品重量与物品数量相比较小

时间:2013-09-16 06:14:55

标签: algorithm knapsack-problem

对于bounded knapsack problem,假设每个项目的值与其权重相同且所有权重都是正整数,我想知道是否存在个别项目权重较小的情况下的优化物品数量背包的容量是所有物品重量总和的一半?例如100k项目和每个项目的重量限制为[1,10]。

算法应该提供精确的解决方案。我知道O(n * W)时间和O(W)空间DP算法,但认为在这种情况下可能有更好的方法来解决它。提前谢谢。

这是来自算法挑战,O(n * W)时间解决方案在功能上是正确的,但不够快(比所需要的速度慢)。我似乎无法找到任何关于这个问题的东西。输入是项目权重列表,所需输出是可以装入背包的项目的最大总值。

2 个答案:

答案 0 :(得分:5)

你正在寻找的论文是Pisinger 1999,“有界权重的背包问题的线性时间算法”。这有点痛苦,因为pdf似乎已经失去了某些变量的区别标记。

以任何顺序将商品添加到您的解决方案,直到您找到商品 b - 商品 - 这会导致您超过 W 。项目 1,2,... b-1 构成平衡填充,所有其他平衡填充是一系列两个操作可以达到的那些:< / p>

  • 平衡插入是将 b 或更高的项目添加到权重为&lt; = W 的平衡解决方案。
  • 平衡删除是从权重&gt;的平衡解决方案中删除 b 之前的项目w ^

很容易看到两件事:首先所有平衡解决方案都在 W 的10个单位内,其次是最佳解决方案必须是平衡解决方案。

我们通过动态编程找到了从初始解决方案到最佳解决方案的方法。

  • 对于 b 以后的每个 t
  • 对于每个权重 w ,使得 W-9&lt; w&lt; W + 10
  • 我们将在 b
  • 之前跟踪最近的项 s
  • 这样可以平衡填充重量 w ,只需在 s t
  • 之间添加/删除项目即可达到>

通过几次阅读。请注意,在此过程中的某些方面,我们保证会遇到最佳解决方案(尽管我们直到最后才知道它)。让 wBreak 成为添加中断项之前的权重,我们的算法被注释为:

for (w = W-9, w <= W, w++) { s(b-1, w) = 0 }
for (w = W+1, w <= W+10, w++) { s(b-1, w) = 1 }

s(b, wBreak) = b - 1

除了 s(b,wBreak)之外,这些都是默认值。然后我们得到肉:

for (t = b, t <= N, t++) 
{
    for (w = W-9, w <= W, w++) 
    {
        // Trying adding item t to the solutions with weight <= W 
        s(t, w + w_t) = max( s(t-1, w), s(t-1, w + w_t) )   
    }
    for (w = W+10, w > W, w--)
    {
        // Removing as many items as needed to get back to a balanced filling
        for (j = s(t, w) - 1, j >= s(t-1, w), j--) 
        {
            s(t, w - w_j) = max( s(t, w - w_j), j )
        }
    }
}

总之,这需要 O(N)时间,我们可以用 s(t,w) > w 最接近 W 但不大于它。

请注意,这并没有利用所有项目的权重之和为2W的事实。我会尝试使用它来考虑简化,但可能是setter添加的问题,因此当没有足够的项目来填充W时,您不必担心琐碎的边缘情况。

答案 1 :(得分:1)

Pisinger 1999论文Bounded背包可以在 http://www.diku.dk/~pisinger/94-27.ps 和实现的代码 http://www.diku.dk/~pisinger/codes.html 如bouknap.c