01背包问题——动态规划法

想真正理解这道题,要先对动态规划法有一定的了解。

下面先介绍我能力范围内所能理解的动态规划法。

动态规划法

(1)阶段

(2)状态(子问题的解)

  #通过对每一阶段,每一状态的目标值(即子问题)的求解与记录,最终求解问题时即借助子问题的最优值来求解最优值。

(3)状态转移方程(某种意义上的递推)

好了,下面开始做题

一个旅行者有一个承重最大为c公斤的背包,现在有n件物品,物品i的重量是wi,其价值为vi。

 

旅行者如何选择装入背包的物品, 使得装入背包中物品的总价值最大? 

第一步 算法模拟

(0)杂七杂八

  用xi表示物品是否放入背包,xi=0则表示未放入背包,xi=1则表示放入背包。

  用vi表示i物品的价值。

  用wi表示i物品的重量。

(1)阶段

  用i表示阶段变量,i=1,2,3,……,n,表示n个物品

(2)状态

  用j表示状态变量,表示背包还能装的物品的重量(0<=j<=C)

(3)状态转移方程(也就是一个递推关系公式)(关键部分)

  Load[i][j]表示前i物品放入承重为j的背包所能得到的最大价值。用此递推公式分阶段一步步求解。

                     0                                                         i = 0 or j = 0    

  Load[i][j] = Load[i-1][j]                                         wi > j  #此时背包放不下i物品,只能放前i-1个物品 

                     max(Load[i-1][j] , Load[i-1][j-wi]+vi)  wi<=j #此时背包可以放下i物品,但要求放与不放的最大值 

  (4)画个表,便于理解(行表示阶段,列表示状态)

   

第二步 编写代码

#(1)定义函数,即状态转移方程
def ZeroOneBag(w,v,c,x):
    #函数的第一部分,求填完后的列表
    Load = [[0 for j in range(c+1)] for i in range(len(w))]
    for i in range(len(w)):
        for j in range(c+1):
            if i == 0 or j == 0:
                Load[i][j] = 0
            elif w[i] > j:
                Load[i][j] = Load[i-1][j]
            else:
                Load[i][j] = max(Load[i-1][j],Load[i-1][j-w[i]]+v[i])


    #函数第二部分,倒推回去,求最优解
    j=c
    for i in range(len(w)-1,0,-1):
        if Load[i-1][j]==Load[i][j]:
            x[i-1] = '未装'
        else:
            x[i-1] = '装'
            j=j-w[i]
    return Load[len(w)-1][c]
#(2)自定义原始数据,例如,背包的承重量为10kg(c=10),有5(n=5)件物品,其重量分别是{2, 2, 6, 5, 4},价值分别为{6, 3, 5, 4, 6}
w = [0,2,2,6,5,4]
v = [0,6,3,5,4,6]
c = 10
x = [0]*(len(w)-1)


#(3)输出结果
totalv = ZeroOneBag(w,v,c,x)
print('物品装入书包的状态:',x)
print('最大值为:',totalv)

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值