0/1背包算法

时间:2016-06-16 19:45:23

标签: algorithm matlab logic dynamic-programming knapsack-problem

我对编程非常陌生,并被要求解决工作计划。现在我们正在处理典型的0/1背包问题,其中在给定质量和体积约束的情况下,效益/值最大化。

我的任务是基本上反转这一点,并在给定值约束的情况下最小化音量或质量。换句话说,我希望我的收益分数大于或等于设定值,然后看看在给定该阈值的情况下我可以获得多少小背包。

我曾尝试在其他地方研究这个问题,并确信它可能有一个正式名称,但我无法找到它。如果有人有任何信息我会非常感激。我有点不知道如何解决这种类型的算法,因为你不能使用相同的递归公式。

2 个答案:

答案 0 :(得分:2)

让我们调用项目i w(i)的权重,以及它的值v(i)。任意订购物品,并将f(i,j)定义为背包的最小可能容量,该背包容纳第一个i项的子集,总计至少为j的值。

要计算f(i,j),我们可以在背包中包含或不包含第i项,所以

f(i>0, j>0) = min(g(i, j), h(i, j))      # Can include or exclude ith item; pick the best
f(_, 0) = 0                              # Don't need any capacity to reach value of 0
f(i<=0, j>0) = infinity                  # Can't get a positive value with <= 0 items

g(i, j) = f(i-1, j)                      # Capacity needed if we exclude ith item
h(i, j) = f(i-1, max(0, j-v(i))) + w(i)  # Capacity needed if we include ith item

在最后一行中,max(0, j-v(i))只确保递归调用f()中的第二个参数在v(i) > j的情况下不会消极。

记忆这给出了假多项式O(nc) - 时间,O(nc) - 空间算法,其中n是项目数,c是值阈值。通过自下而上的方式计算,你可以节省空间(可能是时间,虽然不是渐近的意义) - 这会将空间复杂度降低到O(c),因为在计算f(i, ...)时你只能需要访问f(i-1, ...),因此您只需要保留DP矩阵的前一行和当前“行”。

答案 1 :(得分:0)

如果我理解您的问题,您希望解决的问题在表格中:

let mass_i be the mass of item i, let vol_i the volume, and let val_i be its value.
Let x_i be a binary variable, where x_i is one if and only if the item is in the knapsack.

minimize (mass_1 * x_1 + ... + mass_n * x_n) //The case where you are minimizing mass
s.t.  mass_1 * x_1 + ... + mass_n * x_n >= MinMass
      vol_1 * x_1 + ... + vol_n * x_n   >= MinVolume
      val_1 * x_1 + ... + val_n * x_n   >= MinValue
      x_i in {0,1} for all i

你可以用来制造更多的技巧&#34;背包&#34;将x_i替换为1-y_i,其中y_i为1,当且仅当项目i 在背包中时。然后,您在表单上遇到了同等的问题:

let mass_i be the mass of item i, let vol_i the volume, and let val_i be its value.
Let y_i be a binary variable, where y_i is one if and only if the item is NOT in the knapsack.

maximize mass_1 * y_1 + ... + mass_n * y_n) //The case where you are minimizing mass
s.t.  mass_1 * y_1 - ... + mass_n * y_n <= mass_1 + ... + mass_n - MinMass
       vol_1 * y_1 - ... +  vol_n * y_n <= vol_1 + ... + vol_n - MinVolume
       val_1 * y_1 - ... +  val_n * y_n <= val_1 + ... + val_n - MinValue
      y_i in {0,1} for all i

这是一个有3个约束的背包问题。通过设置x_i = 1 - y_i,可以轻松地将解决方案 y 转换为原始问题的等效解决方案。