01背包熟知的有两种算法,一种回溯法,一种是贪心算法,这是回溯法实现。
public class Knapsack01 {
public static void main(String args[]){
int n=8;
int W=110;
int bestv=0;//最优价值
int[] YN=new int[n+1];//记录是否装入
int[] v={0,11,21,31,33,43,53,55,65};
int[] w={0,1,11,21,23,33,43,45,55};
new Knapsack01().backtracking(v,w,YN,n,W,1);
}
void backtracking(int[] v,int[] w,int[] YN,int n,int W,int i) {
double cw=0;//当前重量
double cv=0;//当前价值
double fp=-1;
double fw=-1;
int k=1;
int[] X=new int[n+1];
while(k<=n+1){//!!!!!!!!!!!!!!
while(k<=n&&cw+w[k]<=W){
cw=cw+w[k];
cv=cv+v[k];
YN[k]=1;
k++;
}
if(k>n){
fp=cv;
fw=cw;
k=n;
for(int j=0;j<n+1;j++)
X[j]=YN[j];
}
else YN[k]=0;
while(Bound(cv,cw,k,W,w,v,n)<=fp){
while(k!=0&&YN[k]!=1)
k--;
if(k==0){
for(int i1=1;i1<n;i1++)
System.out.print(X[i1]);
System.out.println();
System.out.print("value:"+fp+" "+"wight"+fw);
return;
}
YN[k]=0;
cw=cw-w[k];
cv=cv-v[k];
}
k++;
}
}
double Bound(double cv,double cw,int k,int W,int[] w,int[] v,int n){//边界函数,通过比较判断向下还是回溯
double b=cv,c=cw;
for(int i=k+1;i<n;i++){
c=c+w[i];
if(c<W)
b=b+v[i];
else{
double h=b+(1-(c-(double)W)/(double)w[i])*(double)v[i];
return(h);
}
}
return b;
}
}