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;
}
}
自己写的,直接可用。