您的位置:首页 > 其它

动态规划_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实现的代码



代码:

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 

最大价值:12
O啦~~~
转载求保留出处:/article/2121222.html

谢谢!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: