我正在开发一个程序来解决 0/1 背包问题的变体。
此处描述了原始问题:https ://en.wikipedia.org/wiki/Knapsack_problem 。万一以后链接丢失了,我给大家总结一下 0/1 背包问题(如果你熟悉的话,跳过这一段):假设我们有n
物品,每个物品都有重量wi
和价值vi
。我们想把物品放在一个支持最大重量的袋子里,W
这样袋子里的总价值就是最大可能的,而不会使袋子超重。项目不能有多个实例(即,我们每个实例只有一个)。问题的目的是maximize SUM(vi.xi)
使SUM(wi.xi) <= W
和xi = 0, 1
(xi
表示物品在袋子中或不在袋子中的状态)。
就我而言,条件和目标都存在细微差别:
所有物品的重量为1,
wi = 1, i = 1...n
我总是想把一半的东西放在包里。因此,袋子的最大重量容量是物品数量的一半(四舍五入)。
W = ceil[n/2]
或W = floor[(n+1)/2]
。此外,包内的重量必须等于其最大容量
SUM(wi.xi) = W
最后,不是最大化包内物品的价值,而是目标是内部物品的价值尽可能接近外面物品的价值。因此,我的目标是minimize |SUM(vi.-xi) - SUM[vi(1-xi)]|
,它简化为minimize |SUM[vi(2xi - 1)]|
.
现在,在上面的 Wikipedia 页面中有原始 0/1 背包问题的伪代码(您可以在本文底部找到它),但我无法将其适应我的场景。有人可以帮忙吗?(我不是要代码,只是为了一个想法,所以语言无关紧要)
谢谢!
维基百科的 0/1 背包问题的伪代码:
假设
w1, w2, ..., wn, W
是严格的正整数。定义 为在重量小于或等于使用最多(第一个项目)的项目时m[i,w]
可以达到的最大值。w
i
i
我们可以
m[i,w]
递归定义如下:
m[0, w]=0
m[i, w] = m[i-1, w] if wi > w
(新品超过当前重量限制)m[i, w]= max(m[i-1, w], m[i-1, w-wi] + vi) if wi <= w
.然后可以通过计算找到解决方案
m[n,W]
。// Input: // Values (stored in array v) // Weights (stored in array w) // Number of distinct items (n) // Knapsack capacity (W) for j from 0 to W do: m[0, j] := 0 for i from 1 to n do: for j from 0 to W do: if w[i-1] <= j then: m[i, j] := max(m[i-1, j], m[i-1, j-w[i-1]] + v[i-1]) else: m[i, j] := m[i-1, j]