动态规划_01背包问题
2013-11-08 21:27
288 查看
01背包,很经典的背包问题。为什么叫01背包呢?就是有或者没有,或者说一件物品装或者不装进背包。0表示不装,1表示装。好了,01背包问题就是有n个物品P1,P2,P3...Pn,对应的价值分别是V1,V2,V3...Vn。又有一个背包,容量为C。求该背包中能装下物品的最大价值。
动态规划的关键点在于保存当前阶段的所有最优解集合,并使用这些最优解集合在下一阶段中构造新的最优解集合,如此迭代直到最后一个子阶段,这最后一个子阶段中的最优解就是全局最优解。那么我们怎么保证每次计算得到的结果都是当前阶段的最优解呢?这就要通过子问题的分解实现了,子问题的分解就是将问题分解成几个不同情况的子问题,要求这些子问题包含了父问题的所有可能解。那么在某一个求解阶段中,我们只需要的计算这几个子问题的解,并保存其中的最优解。
01背包的子问题分解思想是,讨论是否将第n号物品放进背包(注意是特指“第n号物品,而不是第n件物品",这里必须强调一下,因为我刚开始看书时看出懂,为什么图片第二号后面都是3,明明可以放更大的数吗,后来才想明白,第n行就是针对第n号元素讨论)。不管放还是不放,我们要做的就是得到该子问题的优解。当然前提条件是背包能够放进这第n号物品,所以可以得到该子问题的最优解方程如下:
1.当C<Wn时,f(n,c) = f(n-1,c),即因为根本就放不下,所以f(n,c)除了f(n-1,c)这种最优解外,再没有第二种选择了。
2.当C>=Wn时,f(n,c) = Max{f(n-1,c-Wn)+Vn,f(n-1,c)},其中Max{}中的前者表示放第n号物品,后者表示不放。
上面两式其实就是01背包问题的状态转移表达式。下面看一下图表例子,以及java实现的代码
代码:
运行结果:
转载求保留出处:/article/2121222.html
谢谢!!
动态规划的关键点在于保存当前阶段的所有最优解集合,并使用这些最优解集合在下一阶段中构造新的最优解集合,如此迭代直到最后一个子阶段,这最后一个子阶段中的最优解就是全局最优解。那么我们怎么保证每次计算得到的结果都是当前阶段的最优解呢?这就要通过子问题的分解实现了,子问题的分解就是将问题分解成几个不同情况的子问题,要求这些子问题包含了父问题的所有可能解。那么在某一个求解阶段中,我们只需要的计算这几个子问题的解,并保存其中的最优解。
01背包的子问题分解思想是,讨论是否将第n号物品放进背包(注意是特指“第n号物品,而不是第n件物品",这里必须强调一下,因为我刚开始看书时看出懂,为什么图片第二号后面都是3,明明可以放更大的数吗,后来才想明白,第n行就是针对第n号元素讨论)。不管放还是不放,我们要做的就是得到该子问题的优解。当然前提条件是背包能够放进这第n号物品,所以可以得到该子问题的最优解方程如下:
1.当C<Wn时,f(n,c) = f(n-1,c),即因为根本就放不下,所以f(n,c)除了f(n-1,c)这种最优解外,再没有第二种选择了。
2.当C>=Wn时,f(n,c) = Max{f(n-1,c-Wn)+Vn,f(n-1,c)},其中Max{}中的前者表示放第n号物品,后者表示不放。
上面两式其实就是01背包问题的状态转移表达式。下面看一下图表例子,以及java实现的代码
代码:
package com.wly.algorithmbase.dailyproblem; /** * 用动态规划求解01背包问题 * 状态转移方程: * f(i,j) = Max{f(i-1,j),f(i-1,j-Wi)+Vi},其中j>=Wi * f(i,j) = f(i-1,j),当j < Wi时 * @author wly * */ public class ZeroOnePackageProblem { public static void main(String[] args) { int[] values = {0,3,4,5,7}; int[] weights = {0,2,3,4,5}; int VOLUME = 9; //背包容量 int c[][] = new int[values.length][VOLUME+1]; //这里VOLUME+1,是为表示容积为0的情况 for(int i=0;i<values.length;i++) { c[i][0] = 0; } for(int j=0;j<VOLUME;j++) { c[0][j] = 0; } //使用动态规划填充"可行解表格" for(int i=1;i<c.length;i++) { //注意i从事1开始的特指"1号物品",不是一个物品哦! for(int j=1;j<c[0].length;j++) { //对背包容量的遍历 //填充行元素 if(j >= weights[i]) { //注意是>=,不是> c[i][j] = Math.max(c[i-1][j], c[i-1][j-weights[i]] + values[i]); } else { c[i][j] = c[i-1][j]; //放不下当前遍历的物品,转移状态,子问题为容量j的背包放置前i-1个物品 } } } printArray(c); System.out.println(); System.out.println("最大价值:" + c[c.length-1][c[0].length-1]); } private static void printArray(int[][] array) { for(int i=0;i<array.length;i++) { for(int j=0;j<array[0].length;j++) { System.out.print(array[i][j] + " "); } System.out.println(); } } }
运行结果:
0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 0 0 3 4 4 7 7 7 7 7 0 0 3 4 5 7 8 9 9 12 0 0 3 4 5 7 8 10 11 12 最大价值:12O啦~~~
转载求保留出处:/article/2121222.html
谢谢!!
相关文章推荐
- [动态规划]背包问题九讲(1)----01背包问题
- 动态规划—北大POJ Charm Bracelet(01背包问题)
- 算法导论三剑客之 动态规划 01背包问题
- 动态规划求解01背包问题初探(C版)
- 01背包问题(动态规划)
- 动态规划之01背包问题
- POJ 3624 Charm Bracelet 动态规划(01背包问题)
- 【软考】动态规划之01背包问题
- 北工大算法 作业2 动态规划 01背包问题
- 动态规划之01背包问题
- HDU - 2602(动态规划,01背包问题)
- 动态规划的详细解析(01背包问题)
- 动态规划之01背包问题
- 动态规划之01背包问题(最易理解的讲解)
- 01背包问题,动态规划
- 动态规划——01背包问题
- 动态规划之01背包问题(最易理解的讲解)
- 算法面试---01背包问题---动态规划
- 动态规划之01背包问题
- 动态规划解决——01背包问题