1. 程式人生 > >動態規劃演算法0-1揹包問題java實現

動態規劃演算法0-1揹包問題java實現

問題描述:給定n種物品和一揹包,物品i的重量是wi,其價值是pi,揹包的容量是M,問如何選擇裝入揹包中的物品總價值最大?

import java.util.ArrayList;
import java.util.HashMap;

/*
 * 實際就是一種分而治之的思想
 *   
每次加入新物品i的時候,將總的容量-物品i的容量即是前i-1種物品可以使用的,得出的價值+i的價值
與不加入物品i的價值看誰大
max{f(i-1,w),v(i)+f(i-1,w-wi)} w-wi為扣除i的剩餘容量,在該容量情況下前i-1個物品的最大價值+i的價值與前i-1個物品在總容量不扣除i容量的情況下取更優方案
 * 
 * 
 * 動態規劃是用空間換時間的一種方法的抽象。其關鍵是發現子問題和記錄其結果。然後利用這些結果減輕運算量。因為揹包的最終最大容量未知,
 * 所以,我們得從1到M一個一個的試,看放進去與不放進去哪個選擇更優 */

public class DynamicPlan {

	public static void main(String[] args)
	{
		//第一維下標i表示物品id,第二維下標j表示各個容量值,陣列實際值代表價值,c[0][..]全部賦值為0,以便第一
		int c[][]=new int[4][11];
	ArrayList<ArrayList<Integer>> al=new ArrayList<ArrayList<Integer>>();
	

	//物品1
	
	ArrayList<Integer> al1=new ArrayList<Integer>();
	al1.add(3); //物品大小
	al1.add(4);  //物品價值
	al.add(al1);
	
	
	//物品2
	
	ArrayList<Integer> al2=new ArrayList<Integer>();
	al2.add(4);
	al2.add(5);
	al.add(al2);
	
	
	

	//物品3
	ArrayList<Integer> al3=new ArrayList<Integer>();
	al3.add(5);
	al3.add(6);
	al.add(al3);
	
	for (int a=0;a<=10;a++)
		c[0][a]=0;
	
	int itemcount=al.size();
	for (int i=0;i<itemcount;i++)
	{
		int index=i+1; //物品id從1開始
		for (int j=0;j<=10;j++)
		{
			//如果當前物品的重量小於容量j,才考慮後續處理
			if (al.get(i).get(0)<=j)
			{
				//加入物品i的情況,當前容量(j)減去i的容量即是前i-1種物品可使用的容量,容量下i-1種物品的價值+當前物品i的價值
				//與不加物品i的價值對比
			int temp=Math.max(c[index-1][j-al.get(i).get(0)]+al.get(i).get(1), c[index-1][j]);	
				c[index][j]=temp;
				
					
			}
			else
			{
				c[index][j]=c[index-1][j];
			}
				
				
			
		
		}
		
	}
	
	System.out.println(c[3][10]);
	

	
	}
}

參考: