我对编程非常陌生,并被要求解决工作计划。现在我们正在处理典型的0/1背包问题,其中在给定质量和体积约束的情况下,效益/值最大化。
我的任务是基本上反转这一点,并在给定值约束的情况下最小化音量或质量。换句话说,我希望我的收益分数大于或等于设定值,然后看看在给定该阈值的情况下我可以获得多少小背包。
我曾尝试在其他地方研究这个问题,并确信它可能有一个正式名称,但我无法找到它。如果有人有任何信息我会非常感激。我有点不知道如何解决这种类型的算法,因为你不能使用相同的递归公式。
答案 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 转换为原始问题的等效解决方案。