背包问题的动态规划算法

动态规划方法(用递推公式)

# 背包问题,动态规划求解

#宝物重量'w',和价值'v'
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)])

运行

>>> 
= RESTART: C:/Users/Administrator/Desktop/Python/package_dynamical.py
29
#最大价值是29

递归方法

tr = {(2,3),(3,4),(4,8),(5,8),(9,10)}

#大道最大承重
max_w = 20

#初始化记忆表格m
'''
递归加上备忘录这种技术可以提高程序性能
'''
#key是(宝物组合,最大重量),value是最大价值
m = {}

def thief(tr,w):
    '''
参数:
tr:所有宝物的集合
w:最大负重重量
    '''
    if tr == set() or w == 0 : #递归结束条件
        m[(tuple(tr),w)] =  0 #中间结果在备忘录中记录下来,tuple是key的要求
        return 0
    elif (tuple(tr),w) in m:#如果(tr,w)在备忘录m中,则直接返回
        return m[(tuple(tr),w)]
    else:
        vmax = 0 # 最大价值,先设成最小值
        for t in tr :
            #在tr的宝物中,每次都挑一个出来,把它去掉。剩下的集合就变小了,而且w重量也减了,就减小了问题规模。
           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))

运行:

= RESTART: C:/Users/Administrator/Desktop/Python/递归背包问题.py
29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值