gpt4 book ai didi

Python 背包分支定界法

转载 作者:行者123 更新时间:2023-12-05 05:27:01 24 4
gpt4 key购买 nike

我花了一周的时间编写背包问题的分支定界代码,并且阅读了很多关于该主题的文章和书籍。但是,当我运行我的代码时,我没有得到我期望的结果。从文本文件接收输入,例如:

12
4 1
1 1
3 2
2 3

其中第一行是容量,随后的每一行都是值/权重对。我使用这个文件得到的结果是“8”而不是“10”(除非我弄错了,背包里放不下所有元素)。这是我的代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import Queue
from collections import namedtuple
Item = namedtuple("Item", ['index', 'value', 'weight', 'level', 'bound', 'contains'])

class Node:
def __init__(self, level, value, weight, bound, contains):
self.level = level
self.value = value
self.weight = weight
self.bound = bound
self.contains = contains

def upper_bound(u, k, n, v, w):
if u.weight > k:
return 0

else:
bound = u.value
wt = u.weight
j = u.level + 1

while j < n and wt + w[j] <= k:
bound += v[j]
wt += w[j]
j += 1

# fill knapsack with fraction of a remaining item
if j < n:
bound += (k - wt) * (v[j] / w[j])

return bound

def knapsack(items, capacity):
item_count = len(items)
v = [0]*item_count
w = [0]*item_count

# sort items by value to weight ratio
items = sorted(items, key=lambda k: k.value/k.weight, reverse = True)

for i,item in enumerate(items, 0):
v[i] = int(item.value)
w[i] = int(item.weight)

q = Queue.Queue()

root = Node(0, 0, 0, 0.0, [])
root.bound = upper_bound(root, capacity, item_count, v, w)
q.put(root)

value = 0
taken = [0]*item_count
best = set()

while not q.empty():
c = q.get()

if c.bound > value:
level = c.level+1

# check 'left' node (if item is added to knapsack)
left = Node(c.value + v[level], c.weight + w[level], level, 0.0, c.contains[:])
left.contains.append(level)

if left.weight <= capacity and left.value > value:
value = left.value
best |= set(left.contains)

left.bound = upper_bound(left, capacity, item_count, v, w)

if left.bound > value:
q.put(left)

# check 'right' node (if items is not added to knapsack)
right = Node(c.value, c.weight, level, 0.0, c.contains[:])
right.contains.append(level)
right.bound = upper_bound(right, capacity, item_count, v, w)

if right.bound > value:
q.put(right)

for b in best:
taken[b] = 1

value = sum([i*j for (i,j) in zip(v,taken)])

return str(value)

我的索引关闭了吗?我没有正确遍历树或计算边界吗?

最佳答案

def upper_bound(u, k, n, v, w):
if u.weight > k:
return 0
else:
bound = u.value
wt = u.weight
j = u.level
while j < n and wt + w[j] <= k:
bound += v[j]
wt += w[j]
j += 1
# fill knapsack with fraction of a remaining item
if j < n:
bound += (k - wt) * float(v[j])/ w[j]
return bound


def knapsack(items, capacity):
item_count = len(items)
v = [0]*item_count
w = [0]*item_count
# sort items by value to weight ratio
items = sorted(items, key=lambda k: float(k.value)/k.weight, reverse = True)
for i,item in enumerate(items, 0):
v[i] = int(item.value)
w[i] = int(item.weight)
q = Queue.Queue()
root = Node(0, 0, 0, 0.0,[])
root.bound = upper_bound(root, capacity, item_count, v, w)
q.put(root)
value = 0
taken = [0]*item_count
best = set()
while not q.empty():
c = q.get()
if c.bound > value:
level = c.level+1
# check 'left' node (if item is added to knapsack)
left = Node(level,c.value + v[level-1], c.weight + w[level-1], 0.0, c.contains[:])
left.bound = upper_bound(left, capacity, item_count, v, w)
left.contains.append(level)
if left.weight <= capacity:
if left.value > value:
value = left.value
best = set(left.contains)
if left.bound > value:
q.put(left)
# check 'right' node (if items is not added to knapsack)
right = Node(level,c.value, c.weight, 0.0, c.contains[:])
right.bound = upper_bound(right, capacity, item_count, v, w)
if right.weight <= capacity:
if right.value > value:
value = right.value
best = set(right.contains)
if right.bound > value:
q.put(right)
for b in best:
taken[b-1] = 1
value = sum([i*j for (i,j) in zip(v,taken)])
return str(value)

关于Python 背包分支定界法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22310474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com