动态规划方法解决背包问题
# 物品重量与价值
tr = [None, {'w': 2, 'v': 3}, {'w': 3, 'v': 4},
{'w': 4, 'v': 8}, {'w': 5, 'v': 8}, {'w': 9, 'v': 10}]
# 最大容量
max_w = 20
# 初始化二维表格
# 集合的形式作为二维表格
m = {(i, w): 0 for i in range(len(tr))
for w in range(max_w + 1)}
for i in range(1,len(tr)):
for w in range(1,max_w+1):
if tr[i]['w'] > w:
m[(i,w)] = m[(i-1,w)]
else:
m[(i,w)] = max(m[(i-1,w)],m[(i-1,w-tr[i]['w'])] + tr[i]['v'])
print(type(m))
print(m[(len(tr)-1,max_w)])
递归方法解决背包问题
# 货物重量
# 集合的形式存放
tr = {(2,3),(3,4),(4,8),(5,8),(9,10)}
# 最大载重
max_w = 20
# 初始化记忆表格m
# key是(宝物组合,最大重量),value是最大价值
m={}
def thief(tr,w):
if tr == set() or w == 0:
m[(tuple(tr),w)] = 0 #tuple是key的要求
return 0
elif(tuple(tr),w) in m:
return m[(tuple(tr),w)]
else:
vmax = 0
for t in tr:
if t[0] <= w:
# 逐个从集合中去掉某个宝物,递归调用
# 选出所有价值中最大的值
v = thief(tr-{t}, w-t[0]) + t[1]
vmax = max(vmax,v)
m[(tuple(tr),w)] = vmax
return vmax
print(thief(tr,max_w))
有两点心得,递归更像是不断地剥洋葱,一层一层地剥开,这里面要循环调用自定义函数求解更小规模的子问题。
而动态规划这类问题,要首先在脑海中构造一个表格,这里用到的是一个二维表格,然后有一点必须要记得:动态规划当中地任意一个状态只和前一个状态有关,而与之前状态无关。所以把这个表格填满之后就可以得到动态规划问题的最优解。