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

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

具體問題描述以及C/C++實現參見網址

http://blog.csdn.net/liufeng_king/article/details/8683136

/**
 * 01 揹包問題(動態規劃)
 * @author Lican
 *
 */
public class Pack01 {
	public int[] v;//價值數組
	public int[] w;//重量數組
	public int c;//揹包容量
	public int[][] m;//m(i,j)是揹包容量爲j,可選物品爲,i,i+1,i+2,i+3,...,n 時0-1揹包問題的最優值
	public int[] x;//保存第i個物品是否放入揹包,1:放入;0:未放入
	public Pack01(int[] vv,int[] ww,int cc){
		this.v=vv;
		this.w=ww;
		this.c=cc;
		this.x=new int[vv.length];
		int max = maxM(w,c);//獲取j的最大值,從而通過new關鍵字創建m數組,在內存中維數組分配相應的存儲空間
		m = new int[v.length][max+1];
	}
	/**
	 * 獲取重量和揹包容量的最大值,從而爲m創建相應的存儲空間
	 * @param w
	 * @param c
	 * @return
	 */
	public int maxM(int[] w,int c){
		int max = c;
		for(int i=1;i<w.length;i++){
			if(w[i]>c)
				max=w[i];
		}
		return max;
	}
	public void knapsack(int[] v,int[] w,int c,int[][] m){
		int n =v.length-1;
		int jMax = Math.min(w[n]-1, c);
		for(int j = 0;j <= jMax;j++)
			m[n][j]=0;
		for(int j=w[n];j<=c;j++)
			m[n][j]=v[n];
		for(int i=n-1;i>1;i--){
			jMax=Math.min(w[i]-1,c);
			for(int j=0;j<=jMax;j++)
				m[i][j]=m[i+1][j];
			for(int j=w[i];j<=c;j++)
				m[i][j]=Math.max(m[i+1][j], m[i+1][j-w[i]]+v[i]);
		}
		//m[1][c]=m[2][c];
		if(c>=w[1])//對於i=1時的兩種情況
			m[1][c]=Math.max(m[2][c], m[2][c-w[1]]+v[1]);
		else
			m[1][c]=m[2][c];
		
	}
	public void traceback(int[][] m,int[] w,int c,int[] x){
		int n=w.length-1;
		for(int i=1;i<n;i++){
			if(m[i][c]==m[i+1][c])//第i個包未放入
				x[i]=0;
			else{
				x[i]=1;
				c-=w[i];//c是全局變量
			}
		}
		x[n]=(m[n][c]>0)?1:0;
	}
	public static void main(String[] args) {
		int v[]={0,2,1,4,3};
		int w[]={0,1,4,2,3};
		int c=8;
		Pack01 pa = new Pack01(v,w,c);
		pa.knapsack(pa.v, pa.w, pa.c, pa.m);
		System.out.println("裝入揹包中物品總價值最大爲:");
		System.out.println(pa.m[1][c]);
		pa.traceback(pa.m, pa.w, pa.c, pa.x);
		System.out.println("裝入的物品的序號爲:");
		for(int i=0;i<=v.length-1;i++){
			if(pa.x[i]==1)
				System.out.print(i+" ");
		}
	}
}

運行結果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章