填充2背包的最佳方式?

时间:2013-02-09 10:02:14

标签: algorithm dynamic-programming graph-algorithm knapsack-problem

在一个背包的情况下,最佳地填充背包的动态编程算法很有效。但是,是否有一种有效的已知算法可以最佳地填充2个背包(容量可能不相等)?

我尝试了以下两种方法,但两种方法都不正确。

  1. 首先使用原始DP算法填充第一个背包,填充一个背包,然后填充另一个背包。
  2. 首先填充尺寸为W1 + W2的背包,然后将溶液分成两个溶液(其中W1和W2是两个背包的容量)。
  3. 问题陈述(另见维基百科的Knapsack Problem):

    1. 我们必须用一组物品填充背包(每个物品都有一个重量和一个值),以便最大化我们从物品中获得的价值,同时总重量小于或等于背包尺码。

    2. 我们不能多次使用一个项目。

    3. 我们不能使用项目的一部分。我们不能把一个项目的一小部分。 (每个项目必须完全包含或不包括在内)。

3 个答案:

答案 0 :(得分:11)

我会假设每个n项目只能使用一次,您必须最大化您的利润。

原始背包是dp[i] = best profit you can obtain for weight i

for i = 1 to n do
  for w = maxW down to a[i].weight do
    if dp[w] < dp[w - a[i].weight] + a[i].gain
      dp[w] = dp[w - a[i].weight] + a[i].gain

现在,由于我们有两个背包,我们可以使用dp[i, j] = best profit you can obtain for weight i in knapsack 1 and j in knapsack 2

for i = 1 to n do
  for w1 = maxW1 down to a[i].weight do
    for w2 = maxW2 down to a[i].weight do
      dp[w1, w2] = max
                   {
                       dp[w1, w2], <- we already have the best choice for this pair
                       dp[w1 - a[i].weight, w2] + a[i].gain <- put in knapsack 1
                       dp[w1, w2 - a[i].weight] + a[i].gain <- put in knapsack 2
                   }

时间复杂度为O(n * maxW1 * maxW2),其中maxW是背包可以携带的最大重量。请注意,如果容量很大,则效率不高。

答案 1 :(得分:1)

原始DP假设您在dp数组中标记了您可以在背包中获得的值,并且通过考虑元素来完成更新。
在2个背包的情况下你可以使用2维动态阵列,所以 dp [i] [j] = 1 当你可以把重量 i 放在第一位且重量 j 到第二个背包。更新类似于原始DP案例。

答案 2 :(得分:1)

递归公式是任何人都在寻找:

给定n个项目,使得项目i具有权重wi和值pi。这两个背包具有W1和W2的容量。

对于每0 <= i <= n,0 <= a <= W1,0 <= b <= W2,表示M [i,a,b]为最大值。

对于&lt; 0或b&lt; 0-M [i,a,b] =-∞ 对于i = 0,或a,b = 0-M [i,a,b] = 0

公式: M [i,a,b] = max {M [i-1,a,b],M [i-1,a-wi,b] + pi,M [i-1,a,b-wi] + PI}

i项目问题的每个解决方案都有背包1中的项目i,背包2或其中没有任何项目。