背包问题:用值替换所有项目
Knapsack Problem: Replaces all items with value
我正在尝试通过应用我自己的算法来解决背包问题。我给每个项目一个分数(值[i] - 权重[i])并将高分项目添加到我的背包中。但是此代码将每个项目替换为值 (5) 的第一项。
def knapsack(weights, values, capacity):
knapsack = []
scores = []
for i in range(len(values)):
score = values[i] - weights[i]
scores.append(score)
weight = 0
while weight < capacity:
if len(scores) != 0:
valuable = max(scores)
knapsack.append(values[scores.index(valuable)])
weight += weights[scores.index(valuable)]
scores.pop(scores.index(valuable))
else:
break
return knapsack
weights = [1, 2, 4, 2, 5]
values = [5, 3, 5, 3, 2]
capacity = 10
print(knapsack(weights, values, capacity))
这段代码有什么问题?
编辑:我修复了它,但似乎存在逻辑错误。如果:
weights = [8, 2, 6, 7, 9]
values = [3, 11, 13, 7, 4]
capacity = 24
然后有两个项目得分相同(8, 3 和 9, 4),但 9, 4 更好,因为它正好适合背包并且具有更高的价值。即使将第 8 行更改为 <= 也无济于事。
您也没有从列表中删除附加值。尝试添加
values.pop(scores.index(valuable))
weights.pop(scores.index(valuable))
到 scores.pop(...)
.
之前的行
此外,如果添加的项目会使您超出容量,则需要跳出循环,例如:
if (weight + weights[scores.index(valuable)]) > capacity:
break
您需要代码来处理决胜局,它将分数索引重新分配给适合容量的最高值项目,例如:
ties = [i for i, x in enumerate(scores) if x == valuable]
if len(ties) > 1:
most_valuable = -1
for idx in ties:
if values[idx] > most_valuable and (weight + weights[idx]) <= capacity:
most_valuable = values[idx]
scores_idx = idx
完整代码:
def knapsack(weights, values, capacity):
knapsack = []
scores = []
for i in range(len(values)):
score = values[i] - weights[i]
scores.append(score)
weight = 0
while weight < capacity:
if len(scores) != 0:
valuable = max(scores)
scores_idx = scores.index(valuable)
ties = [i for i, x in enumerate(scores) if x == valuable]
if len(ties) > 1:
most_valuable = -1
for idx in ties:
if values[idx] > most_valuable and (weight + weights[idx]) <= capacity:
most_valuable = values[idx]
scores_idx = idx
if (weight + weights[scores_idx]) > capacity:
break
knapsack.append(values[scores_idx])
weight += weights[scores_idx]
values.pop(scores_idx)
weights.pop(scores_idx)
scores.pop(scores_idx)
else:
break
return knapsack
# weights = [1, 2, 4, 2, 5]
# values = [5, 3, 5, 3, 2]
# capacity = 10
weights = [8, 2, 6, 7, 9]
values = [3, 11, 13, 7, 4]
capacity = 24
print(knapsack(weights, values, capacity))
我正在尝试通过应用我自己的算法来解决背包问题。我给每个项目一个分数(值[i] - 权重[i])并将高分项目添加到我的背包中。但是此代码将每个项目替换为值 (5) 的第一项。
def knapsack(weights, values, capacity):
knapsack = []
scores = []
for i in range(len(values)):
score = values[i] - weights[i]
scores.append(score)
weight = 0
while weight < capacity:
if len(scores) != 0:
valuable = max(scores)
knapsack.append(values[scores.index(valuable)])
weight += weights[scores.index(valuable)]
scores.pop(scores.index(valuable))
else:
break
return knapsack
weights = [1, 2, 4, 2, 5]
values = [5, 3, 5, 3, 2]
capacity = 10
print(knapsack(weights, values, capacity))
这段代码有什么问题?
编辑:我修复了它,但似乎存在逻辑错误。如果:
weights = [8, 2, 6, 7, 9]
values = [3, 11, 13, 7, 4]
capacity = 24
然后有两个项目得分相同(8, 3 和 9, 4),但 9, 4 更好,因为它正好适合背包并且具有更高的价值。即使将第 8 行更改为 <= 也无济于事。
您也没有从列表中删除附加值。尝试添加
values.pop(scores.index(valuable))
weights.pop(scores.index(valuable))
到 scores.pop(...)
.
此外,如果添加的项目会使您超出容量,则需要跳出循环,例如:
if (weight + weights[scores.index(valuable)]) > capacity:
break
您需要代码来处理决胜局,它将分数索引重新分配给适合容量的最高值项目,例如:
ties = [i for i, x in enumerate(scores) if x == valuable]
if len(ties) > 1:
most_valuable = -1
for idx in ties:
if values[idx] > most_valuable and (weight + weights[idx]) <= capacity:
most_valuable = values[idx]
scores_idx = idx
完整代码:
def knapsack(weights, values, capacity):
knapsack = []
scores = []
for i in range(len(values)):
score = values[i] - weights[i]
scores.append(score)
weight = 0
while weight < capacity:
if len(scores) != 0:
valuable = max(scores)
scores_idx = scores.index(valuable)
ties = [i for i, x in enumerate(scores) if x == valuable]
if len(ties) > 1:
most_valuable = -1
for idx in ties:
if values[idx] > most_valuable and (weight + weights[idx]) <= capacity:
most_valuable = values[idx]
scores_idx = idx
if (weight + weights[scores_idx]) > capacity:
break
knapsack.append(values[scores_idx])
weight += weights[scores_idx]
values.pop(scores_idx)
weights.pop(scores_idx)
scores.pop(scores_idx)
else:
break
return knapsack
# weights = [1, 2, 4, 2, 5]
# values = [5, 3, 5, 3, 2]
# capacity = 10
weights = [8, 2, 6, 7, 9]
values = [3, 11, 13, 7, 4]
capacity = 24
print(knapsack(weights, values, capacity))