package knapsack;
public class Knasack_Backtracking {
/*
* 使用回溯法實現01揹包問題
*/
/**有4件物品*/
static final int n=4;
/**揹包最大承重爲9*/
static final int maxWeight=9;
/**4件物品的重量*/
static double weight[]={0,2,3,4,5};
/**4件物品的價值*/
static double value[]={0,3,4,5,7};
/**揹包中當前重量*/
static int currentWeight=0;
/**揹包中當前價值*/
static int currentValue=0;
/**當前最優價值*/
static int bestValue=0;
/**物品*/
static Item items[]=new Item[n+1];
/**記錄當前規則中物品放了與否*/
static int x[]=new int[n+1];
/**記錄最優規則的物品放了與否*/
static int bestX[]=new int[n+1];
public static void main(String[] args) {
items[0]=new Item(0,0);
for(int i=1;i<=n;i++){
items[i]=new Item(i,value[i]/weight[i]);
}
//使用冒泡排序,按照每個物品的單位質量的價格降序排列
for(int i=1;i<=n;i++){
for(int j=1;j<=n-i;j++){
if(items[j].averagePrice<items[j+1].averagePrice){
items[0].id=items[j+1].id;
items[0].averagePrice=items[j+1].averagePrice;
items[j+1].id=items[j].id;
items[j+1].averagePrice=items[j].averagePrice;
items[j].id=items[0].id;
items[j].averagePrice=items[0].averagePrice;
}
}
}
System.out.print("最優時選擇");
backtrack(1);
for(int i=1;i<=n;i++){
if(bestX[i]==1)
System.out.print(" 第"+i+"件 ");
}
System.out.print("物品,最優值爲"+bestValue);
}
/**回溯算法
* @param t 當前層數*/
public static void backtrack(int t){
if(t>n){//超出層數,當前揹包中的價值就是最優值
bestValue=currentValue;
for(int j=0;j<=n;j++)
bestX[j]=x[j];
return;
}
//可以放入下一個物品
if(currentWeight+weight[items[t].id]<=maxWeight){
x[items[t].id]=1;
currentWeight+=weight[items[t].id];
currentValue+=value[items[t].id];
backtrack(t+1);
currentWeight-=weight[items[t].id];
currentValue-=value[items[t].id];
}
if(bound(t+1)>bestValue){//進入右子樹
x[items[t].id]=0;
backtrack(t+1);
}
}
/**
* 進入右子樹時計算上界
* @param t 層數*/
public static double bound(int t){
double topBound=currentValue;//上界
double leftWeight=maxWeight-currentWeight;
//將整件物品放入
while(t<=n&&leftWeight>=weight[items[t].id]){
leftWeight-=weight[items[t].id];
topBound+=value[items[t].id];
t++;
}
//不能整件放入的切開放
if(t<=n)
topBound+=leftWeight*items[t].averagePrice;
return topBound;
}
}
class Item{
/**物品編號*/
int id;
/**該物品單位質量的價格*/
double averagePrice;
public Item(int id,double averagePrice){
this.id=id;
this.averagePrice=averagePrice;
}
}
自己寫的,直接可用。