【发布时间】:2021-08-21 08:01:33
【问题描述】:
我尝试了给定 here 的实现,使用 Branch and Bound 解决背包问题。
该解决方案看起来不错,但它并没有使最终选定的项目达到最佳值。 有没有办法通过最低限度地更改以下代码来实现这一点?
import sys
def bound(vw, v, w, idx):
if idx >= len(vw) or w > limit:
return -1
else:
while idx < len(vw) and w + vw[idx][1] <= limit:
v, w, idx = v + vw[idx][0], w + vw[idx][1], idx + 1
if idx < len(vw):
v += (limit - w) * vw[idx][0] / (vw[idx][1] * 1.0)
return v
def knapsack(vw, limit, curValue, curWeight, curIndex):
global maxValue
if bound(vw, curValue, curWeight, curIndex) >= maxValue:
if curWeight + vw[curIndex][1] <= limit:
maxValue = max(maxValue, curValue + vw[curIndex][0])
knapsack(vw, limit, curValue + vw[curIndex][0], curWeight + vw[curIndex][1], curIndex + 1)
if curIndex < len(vw) - 1:
knapsack(vw, limit, curValue, curWeight, curIndex + 1)
return maxValue
maxValue = 0
if __name__ == '__main__':
with open(sys.argv[1] if len(sys.argv) > 1 else sys.exit(1)) as f:
n, limit = map(int, f.readline().split())
vw = []
taken = n * [0]
for ln in f.readlines():
vl, wl = map(int, ln.split())
vw.append([vl, wl, vl / (wl * 1.0)])
print(knapsack(sorted(vw, key=lambda x: x[2], reverse=True), limit, 0, 0, 0))
print(taken)
假设我们有一个包含以下内容的输入文件
4 11
8 4
15 8
4 3
10 5
我期待如下结果
19
0 1 1 0
我写了自己的implementation,它提供了上述所需的输出,但对于像one这样的大问题,它花费的时间太长了
【问题讨论】:
-
限制在main中定义。
-
那很难看。所以
knapsack得到了参数,bound没有,但它们都使用相同的值。 -
好吧,这就是 OP 所写的。它并没有给我带来太多困扰,因为只要它有效,这不是我关心的问题。
标签: python algorithm optimization knapsack-problem branch-and-bound