给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。
问应如何选择装入背包的物品,使得在总重量不超过背包的容量C的前提下装入背包中物品的总价值最大?
package com.lanxi.demo1;
public class Package {
static int n = 5;//给定物品数
int capacity = 15;//背包容量
int[] weight = {3,6,1,2,7};//物品重量
double[] value = {6,5,9,2,7};//物品价值
int maxValue = 0;//最大价值
int tempValue;
int tempWeight;
int[] way = new int[n];//存放方式
static int[] bestWay = new int[n];//价值最大存放方式
public void BackTrack(int t){
//已经搜索到根节点
if(t>n-1){
if(tempValue > maxValue){
maxValue = tempValue;
for(int i=0;i
bestWay[i] = way[i];
}
return ;
}
//搜索左边节点
if(tempWeight + weight[t] <= capacity){
//总的放入的物品重量要小于背包
tempWeight += weight[t];//质量加
tempValue += value[t];//价值加
way[t] = 1;//放入后赋值为1
BackTrack(t+1);
tempWeight -= weight[t];
tempValue -= value[t];
way[t] = 0;
}
//不装入这个物品,直接搜索右边的节点
if( Bound(t+1) >= maxValue){
BackTrack(t+1);
}
}
//用于计算剩余物品的最高价值上界
public double Bound(int k){
double maxLeft = tempValue;
int leftWeight = capacity - tempWeight;//剩余背包容量
//尽力依照单位重量价值次序装剩余的物品
while(k <= n-1 && leftWeight > weight[k] ){
leftWeight -= weight[k];
maxLeft += value[k];
k++;
}
//不能装时,用下一个物品的单位重量价值折算到剩余空间。
if( k <= n-1){
maxLeft += value[k]/weight[k]*leftWeight;
}
return maxLeft;
}
public static void main(String[] args){
Package b = new Package();
b.BackTrack(0);//设第1个商品序列号为0
System.out.println("该背包能够取到的最大价值为:"+b.maxValue);
System.out.println("取出的方法为:");
for (int i = 0; i < n; i++) {
System.out.print(bestWay[i]+" ");
}
}
}