1. 程式人生 > >0-1揹包問題(回溯法)

0-1揹包問題(回溯法)

0-1揹包:給定n種物品和一揹包。物品i的重量是wi,其價值為vi,揹包的容量為C。問應如何選擇裝入揹包的物品,使得在總重量不超過揹包的容量C的前提下裝入揹包中物品的總價值最大。

package 實驗五;
import java.util.Scanner;
public class 揹包問題 {

	public static void main(String[] args) {
		Bag b=new Bag();
		b.Set();
		b.Input();
		b.Backtrack(0);
		b.Output();
	}

}
class Bag{
	int c;         //揹包容量
	int n;        //物品數量
	int [] w;       //各物品重量
	int [] p;       //各物品價值
	int [] x;       //解向量
	int cw;      //當前重量
	int cv;      //當前價值
	int bestv;  //當前最優價值
	int [] bestx;  //當前最優價值對應的解
	Bag(){
		n=0; 
		cw=cv=bestv=0;
	}
	void Set(){
		System.out.println("請輸入物品數量:");
		Scanner reader=new Scanner(System.in);
		n=reader.nextInt();
		this.n=n;
		x=new int[n];
		p=new int[n];
		w=new int[n];
		bestx=new int[n];
	}
	void Input()
	{
		int i;
		Scanner reader=new Scanner(System.in);
		System.out.println("請輸入揹包容量:");
		c=reader.nextInt();
		System.out.println("請輸入各物品重量:");
		for (i=0; i<n; i++)
			w[i]=reader.nextInt();
		System.out.println("請輸入各物品價值:");
		for (i=0; i<n; i++)
			p[i]=reader.nextInt();
	}
	void Output(){
		int i;
		for (i=0;i<n; i++)
			System.out.print(bestx[i]+" ");
		System.out.println();
	}
	void Backtrack(int t)
	{
	   if (t>n-1)
	   {
		   if (cv>bestv)
		   {
			   bestv=cv;
			   for (int i=0; i<n; i++)
				   bestx[i]=x[i];
		   }
	   }
	   else
	   {
		   for (int i=0; i<=1; i++) 
		   { 
			   x[t]=i;
		       if (i==0)
			      Backtrack(t+1);
		       else
		         if(cw+w[t]<=c)
				 {
				   cw=cw+w[t];
				   cv=cv+p[t];
				   Backtrack(t+1);
				   cw=cw-w[t];
				   cv=cv-p[t];
				 }
		   }
	   }
	}
}

請輸入物品數量: 3 請輸入揹包容量: 30 請輸入各物品重量: 16 15 15 請輸入各物品價值: 45 25 25 0 1 1