[英]Trying to find the optimal subset for the Greedy knapsack problem(python)
我认为这是找到最佳值的正确算法,但现在我需要找到获得该值的最佳子集。 帮助将不胜感激!
这些是我的方向:实现一个贪心算法,按价值与重量比的降序排列项目(vi/wi for i = 1, 2, ..., n),然后 select 按此顺序排列项目,直到重量下一个项目超过剩余容量(注意:在这个贪婪版本中,我们在第一个包含超过背包容量的项目之后立即停止)。
def greedy_knapsack(val, weight, W, n):
# index = [0, 1, 2, ..., n - 1] for n items
index = list(range(len(val)))
# contains ratios of values to weight
ratio = [v / w for v, w in zip(val, weight)]
QuickSort(ratio, 0, len(ratio) - 1)
max_value = 0
for i in index:
if weight[i] <= W:
max_value += val[i]
W -= weight[i]
else:
max_value += val[i] * W // weight[i]
break
return max_value
在许多情况下,你的贪婪方法会失败。
一个这样的微不足道的案例:
weight = [10, 10, 10]
value = [5, 4, 3]
W = 7
在这种情况下,您的算法将选择 (项目 1) sum = 5,但最佳答案应该是 (项目 2 和 3),总和 = 7。
您需要一种动态编程方法来解决这个问题,并且您可以保留一个矩阵来存储您以前的状态,以便您可以重建解决方案并获取项目列表。
# Prints the items which are put in a
# knapsack of capacity W
def printknapSack(W, wt, val, n):
K = [[0 for w in range(W + 1)]
for i in range(n + 1)]
# Build table K[][] in bottom
# up manner
for i in range(n + 1):
for w in range(W + 1):
if i == 0 or w == 0:
K[i][w] = 0
elif wt[i - 1] <= w:
K[i][w] = max(val[i - 1]
+ K[i - 1][w - wt[i - 1]],
K[i - 1][w])
else:
K[i][w] = K[i - 1][w]
# stores the result of Knapsack
res = K[n][W]
print(res)
w = W
for i in range(n, 0, -1):
if res <= 0:
break
# either the result comes from the
# top (K[i-1][w]) or from (val[i-1]
# + K[i-1] [w-wt[i-1]]) as in Knapsack
# table. If it comes from the latter
# one/ it means the item is included.
if res == K[i - 1][w]:
continue
else:
# This item is included.
print(wt[i - 1])
# Since this weight is included
# its value is deducted
res = res - val[i - 1]
w = w - wt[i - 1]
# Driver code
val = [ 60, 100, 120 ]
wt = [ 10, 20, 30 ]
W = 50
n = len(val)
printknapSack(W, wt, val, n)
参考: https://www.geeksforgeeks.org/printing-items-01-knapsack/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.