动态规划之背包问题 python实现
来源:互联网 发布:js dialog 关闭事件 编辑:程序博客网 时间:2024/06/13 04:23
动态规划之01背包问题
题目描述:有编号分别为1,2,3,4,5的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
动态规划的核心过程有两部分,一个是找出问题的”子状态”,再一个就是建立“状态转移方程”(所谓的递推公式)。将上面的问题解决,动态规划就解了一般,剩下的为代码将数学的公式的进行实现。
- 动态规划的思路。先将原始问题一般化,欲求背包能够获得的总价值,即欲求前i个物体放入容量为m(kg)背包的最大价值c[i][m]——使用一个数组来存储最大价值,当m取10,i取3时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。下面使用数学表达式描述它们两者之间的具体关系。
- w[i]:第i个物体的重量
- p[i]:第i个物体的价值
- c[i][j]:前i个物体放入容量为j 包的最大价值
- c[i-1][j]:前i个物体放入容量为j 包的最大价值
- c[i-1][j-w[i]]:前i-1个物体放入容量为j-w[i] 包的最大价值
以下通过表格来说状态转移方程
c[i][m]=max{c[i-1][m-w[i]]+p[i](m>w[i]) , c[i-1][m]}
首先明确该表是至底向上,从左到生成的。且上边abcde带代表编号5,4,3,2,1
- c[3][2]代表 编号1,2,3三件物品放入容量为2的包中的最大价值。因为编号1,2,3的任一件物品的重量都要大于2,装入容量为2的包。即w[i]>2(i=1,2,3) 故c[3][2]=0
- 现在通过思考c[5][8]=15的由来理解上式的状态转移方程
- 根据c[i][m]=max{c[i-1][m-w[i]]+pi(m>w[i]) , c[i-1][m]}公式,需要考虑c[4][8-w[5]]+p[5]=9+6=15, c[4][8]=9, c[5][8]=15
当逐步推出表中每个值的大小,那个最大价值就求出来了。推导过程中,注意一点,最好逐行而非逐列开始推导,先从编号为1的那一行,推出所有c[1][m]的值,再推编号为2的那行c[2][m]的大小。这样便于理解。
- 根据c[i][m]=max{c[i-1][m-w[i]]+pi(m>w[i]) , c[i-1][m]}公式,需要考虑c[4][8-w[5]]+p[5]=9+6=15, c[4][8]=9, c[5][8]=15
以下开始用python编程
#n:物品件数;c:最大承重为c的背包;w:各个物品的重量;v:各个物品的价值#第一步建立最大价值矩阵(横坐标表示[0,c]整数背包承重):(n+1)*(c+1)#技巧:python 生成二维数组(数组)通常先生成列再生成行def bag(n,c,w,p): res=[[-1 for j in range(c+1)]for i in range(n+1)] for j in range(c+1): #第0行全部赋值为0,物品编号从1开始.为了下面赋值方便 res[0][j]=0 for i in range(1:n+1): for j in range(1:c+1): res[i][j]=res[i-1][j] #生成了n*c有效矩阵,以下公式w[i-1],p[i-1]代表从第一个元素w[0],p[0]开始取。 if(j>=w[i-1]) and res[i-1][j-w[i-1]]+p[i-1]>res[i][j]: res[i][j]=res[i-1][j-w[i-1]]+p[i-1] return res#以下代码功能:标记出有放入背包的物品#反过来标记,在相同价值情况下,后一件物品比前一件物品的最大价值大,则表示物品i#有被加入到背包,x数组设置为True。设初始为j=c。def show(n,c,w,res): print('最大价值为:',res[n][c]) x=[False for i in range(n)] j=c for i in range(1,n+1): if res[i][j]>res[i-1][j]: x[i-1]=True j-=w[i-1] print '选择的物品为:' for i in range(n): if x[i]: print '第',i,'个,' print'' if __name__=='__main__': n=5 c=10 w=[2,2,6,5,4] p=[6,3,5,4,6] res=bag(n,c,w,p) show(n,c,w,res)
爱奇艺算法题
该题与背包问题有以下等价
- 节目数等价于物品数n
- 采购预算金额B等价于背包承受总重c
- 每个节目的价格P[i]等价于每个物品的重量w[i]
- 每个节目的播放量V[i]等价于每个物品的价值p[i]
现在解决的问题为总金额不超过B的前提下获得最高的预期值播放量?
等价于不超过背包称重量c的前提下获得最高的物品价值?
先输入流数据进行处理:
#转化为列表之后不能直接int(List)n=int(sys.stdin.readline().strip())#正确解法:需要对列表内每个数int();使用raw_input()不会读取回车,sys.stdin()会读取回车键dat=[int(x) for x in raw_input().strip().split()]c=dat[0];p=[];v=[]m=len(dat)for i in range(1,m,2): p.append(dat[i])for j in range(2,m,2): v.append(dat[j])
数据处理完后将对应的带入背包问题的bag函数中即可得到结果。
阅读全文
0 0
- 动态规划之背包问题 python实现
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- gpg加密文件
- ViewPager PageTransformer探索
- Ubuntu下安装MySQL
- oracle一个创建用户、创建表空间、授权、建表的完整过程
- 顺序线性表-数据结构(1)
- 动态规划之背包问题 python实现
- BM系列之 架构
- java web学习推荐博客
- PHP获取汉字首字母
- servlet生命周期
- springMvc注解@RequestParam用法解析
- 20170515_使用异或运算求出孤独数
- loadrunner性能测试_第二步 运行负载测试
- IOS远程消息推送