0-1背包问题
"""
动态规划问题
基本思想:参考合并排序算法
分而治之理念
"""
"""
功能描述:自定义背包函数,实现动态规划算法
参数说明:count:表示物品件数
TotalWeight:表示背包的总容量
weight:表示每件物品的重量
cost:表示每件物品的价值
"""
import numpy as np
# 用常规方案实现功能
def bag(count, TotalWeight, weight, cost):
# value = [[0 for j in range(TotalWeight + 1)] for i in range(count + 1)] # 置零,表示初始状态
value = np.array([[0] * (TotalWeight + 1)] * (count + 1)) # numpy 实现
# print(value)
for i in range(1, count+1): # 遍历物品件数,从第1件物品计算
for j in range(1, TotalWeight + 1): # 遍历背包容纳量,从重量为1开始计算
value[i][j] = value[i - 1][j] # 定义value数组存储最大价值
print(value)
# 背包总容量够放当前物体,遍历前一个状态考虑是否置换
if j >= weight[i - 1] and value[i][j] < value[i - 1][j - weight[i - 1]] + cost[i - 1]:
value[i][j] = value[i - 1][j - weight[i - 1]] +cost[i - 1] # 最大价值就是 当前物品的价值+剩余空间的价值
return value # 返回最大价值
# 用numpy实现如上功能
def fun(n, W, w, p):
a = np.array([[0] * (W + 1)] * (n + 1))
# 依次计算前i个行李的最大价值,n+1在n的基础上进行
for i in range(1, n + 1):
for j in range(1, W + 1):
if w[i - 1] > j:
a[i][j] = a[i - 1][j]
else:
a[i, j] = max(a[i - 1, j], p[i - 1] + a[i - 1, j - w[i - 1]]) # 2种情况取最大值
findDetail(p, n, a[n, W])
# 找到价值列表中的一个子集,使得其和等于前面求出的最大价值,即为选择方案
def findDetail(p, n, v):
a = np.array([[True] * (v + 1)] * (n + 1))
for i in range(0, n + 1):
a[i][0] = True
for i in range(1, v + 1):
a[0][i] = False
for i in range(1, n + 1):
for j in range(1, v + 1):
if p[i - 1] > j:
a[i, j] = a[i - 1, j]
else:
a[i, j] = a[i - 1, j] or a[i - 1, j - p[i - 1]]
if a[n, v]:
i = n
result = []
while i >= 0:
if a[i, v] and not a[i - 1, v]:
result.append(p[i - 1])
v -= p[i - 1]
if v == 0:
break
i -= 1
print(result)
else:
print('error')
"""
功能:自定义显示输出结果函数
参数说明: count:表示物品件数
TotalWeight:表示背包的总容量
weight:表示每件物品的重量
value:表示最大价值,即所求的结果
"""
def show(count, TotalWeight, weight, value):
x = [False for i in range(count)] # 初始化x,使得x为假
j = TotalWeight # 背包的容量赋给变量j
for i in range(count, 0, -1): # 遍历每个物品
if value[i][j] > value[i - 1][j]: # 如果value[i][j]单元格大于上一行同列的单元格的价值,进行更新
x[i - 1] = True
j -= weight[i - 1] # 总容量减去上一行同列的单元格的重量
print('最大价值为:', value[count][TotalWeight]) # 输出最大价值的值
print('背包中所装物品为:')
for i in range(count): # 遍历物品数
if x[i]: # 判断最大价值的物品数
print('第', i + 1, '个 ', end='') # 输出是第几个物品
count = 3 # 一共有3件物品
TotalWeight = 4 # 背包的总容量是4
weight = [1, 4, 3] # 每个物品的重量
cost = [4900, 7800, 5600] # 每个物品的价值
value = bag(count, TotalWeight, weight, cost) # 调用bag()函数动态规划算法函数
# show(count, TotalWeight, weight, value) # 调用show()函数输出结果