1. 动态规划算法
动态规划算法是将待解决的问题拆分成一系列相互交叠的子问题,它的基本思想与合并排序算法类似,也是将待求解的问题分解为若干个子问题(阶段)。动态规划算法需要按顺序求解子问题,前一子问题的解为后一子问题的求解提供了有用的信息。在求解任何一个子问题时,都要列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题后,那么最后一个子问题就是初始问题的解。简单来说,就是不要让程序做重复的事情。
2. 背包问题
有n件物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值。装包条件是一种商品只能装一个。
最简单的方法是尝试使用各种可能的物品组合,找出价值最高的组合。
这种办法是可以的,但是速度非常慢,对于三件物品就需要8次不同组合比较。如果有四件物品,则需要计算更多的组合。很显然,当物品数量增多时,简单组合方法的速度会变慢,从最优算法角度考虑,这种算法是不可行的。接下来通过动态规划算法快速地找出最优组合。
动态规划算法就是将大问题变成小问题,通过解决小问题逐步解决大问题。因此将大背包变成小背包问题,按照物品的重量分成小背包(即1kg、2kg、3kg、4kg的小背包)。
通过公式计算出每个单元格的价值,并最终得到最大价值的过程就是将大问题拆成小问题,最后再合并大问题,从而得出了大问题的解。而这个解题的过程就是动态规划算法。
接下来用Python代码来实现“背包问题”,具体代码如下:
"""
功能:自定义背包函数,实现动态规划算法
参数说明: count:表示物品件数
TotalWeight:表示背包的总容量
weight:表示每件物品的重量
cost:表示每件物品的价值
"""
def bag(count, TotalWeight, weight, cost):
# 置零,表示初始状态
value = [[0 for j in range(TotalWeight + 1)] for i in range(count +1)]
for i in range(1, count+1): # 遍历物品件数,从第1件物品计算
for j in range(1, TotalWeight + 1): # 遍历背包容纳量,从重量为1开始计算
value[i][j] = value[i - 1][j] # 定义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]
for x in value: # 遍历输出背包网格
print(x)
return value # 返回最大价值
"""
功能:自定义显示输出结果函数
参数说明: 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): # 遍历每个物品
# 如果value[i][j]单元格大于上一行同列的单元格的价值,进行更新
if value[i][j] > value[i - 1][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()函数输出结果