问题:
现在有一个背包,总容量为bag_weight, 现在有n种物品,每种物品只有1件,它们的重量w与价值v如下,请问怎么选取物品,可以使得背包装的物品价值最大?
n = 6
bag_weight = 10
w = [2, 2, 3, 1, 5, 2]
v = [2, 3, 1, 5, 4, 3]
实现思路:
value[i][j]:表示当背包剩余容量为j,现在有前i件物品可放的情况下,背包所能装物品的最大价值。value[4][8]表示当背包剩余容量为8,现在有前4件物品可放的情况下,背包所能装物品的最大价值。
value[i][j] 等于下列两种情况:
1. 当第i 件物品重量大于j ,那么第i件物品放不进去,价值和i-1相等。
value[i][j] = value[i - 1][j]
2. 当第i件物品的重量不大于j时 ,那么第i件物品可以放进去,最大价值取放与不放最大值。
value[i][j] = max(value[i - 1][j], value[i - 1][j - w[i]] + v[i])
w[i ] 为第i件物品的容量,v[i]为第i件物品的价值。
代码:
def fun(n, bag_weight, w, v):
'''
:param n: #物品数量
:param bag_weight: 背包重量
:param w: 每个物品重量
:param v: 每个物品价值
:return:
'''
# 初始化,先全部赋值为0,这样至少体积为0或者不选任何物品的时候是满足要求
value = [[0 for j in range(bag_weight + 1)] for i in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, bag_weight + 1):
value[i][j] = value[i - 1][j] # 第i个物品不选
if j >= w[i-1]: # 判断剩余背包容量是不是大于第i件物品的体积
value[i][j] = max(value[i - 1][j], value[i - 1][j - w[i - 1]] + v[i - 1])
# for i in value:
# print(i)
return value
求背包中的物品,从尾遍历物品,当value大于上一行同样位置的value时,表示放进该物品。
def show(n, bag_weight, w, value):
print('背包最大价值为:', value[n][bag_weight])
x = [False for i in range(n)]
j = bag_weight
# 从尾遍历物品,当value大于上一行同样位置的value时,表示放进该物品
for i in range(n, 0, -1):
if value[i][j] > value[i - 1][j]:
x[i - 1] = True
j -= w[i - 1]
print('背包中所装物品为:')
for i in range(n):
if x[i]:
print('第', i + 1, '个', end='\t')
n = 6 bag_weight = 10 w = [2, 2, 3, 1, 5, 2] v = [2, 3, 1, 5, 4, 3] value = fun(n, bag_weight, w, v) show(n, bag_weight, w, value) # 背包最大价值为: 15 # 背包中所装物品为: # 第 2 个 第 4 个 第 5 个 第 6 个