29、数据结构与算法Python:动态规划案例分析

讨论:博物馆大盗问题

大盗潜入博物馆, 面前有5件宝物, 分别有重量和价值, 大盗的背包仅能负重20公斤, 请问如何选择宝物, 总价值最高?

*

我们把m(i, W)记为:

前i(1<=i<=5)个宝物中,组合不超过W(1<=W<=20) 重量,得到的最大价值m(i, W),应该是m(i-1, W)和m(i-1, W-Wi)+vi,两者最大值我们从m(1, 1)开始计算到m(5, 20)
*

博物馆大盗问题:动态规划表格

*

递归解法

# 宝物的重量和价值
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) in m] = 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))

动态规划

# 宝物的重量和价值
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)]
# 表示前i个宝物中,最大重量w的组合,所得到的最大价值
# 当i什么都不取,或w上限为0,价值均为0
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: # 装不下第i个宝物
            m[(i, w)] = m[(i-1), w] # 不装第i个宝物
        else:
            # 不装第i个宝物, 装第i个宝物,两种情况下最大价值
            m[(i, w)] = max(m[(i-1, w)], m[(i-1, w-tr[i]['w'])] + tr[i]['v'])

# 输出结果
print(m[(len(tr)-1, max_w)])

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: