问题描述:有 n 个中联那个分别为{w1,w2.....wn}的物品,他们的价值分别为{v1,v2....vn},给定一个熔炼那个为 W 的背包。设计从这些物品中选取一部物品放入该背包的方案,每个物品要么选中要么不选中,要求选中的物品不仅能够放到背包中,而且具有最大的价值。根据下图求出 W = 7 时的所有结和最佳结果。
这道题最简单的思路就是暴力破解,利用穷举法列举所有可能性,,输出每一种可能性,然后从中选出一个最优解,输出就行了。当然有比这个要好的思路,就是用动态规划。
动态规划部分后期更新,暂时先写暴力破解的方法。
coding.......
public class BeiBao {
static int data[][] = new int[20][20];
static int size=4,len=1; //size 表示物品数量,W表示背包容量,len保存子集的个数
public static void main(String[] args) {
int w[] = {5,3,2,1}; //物品
int v[] = {4,4,3,1}; //物品对应重量
int W = 7;
pset();
knap(w,v,W);
}
/*
* 数组的复制
*/
static void copy(int a[],int b[],int len) {
for(int i=0;i<=len;i++)
b[i]=a[i];
}
/*
* 计算 1~n 的幂集
*/
static void pset() {
int a[] = new int[10]; //临时保存一个子集
int m;
data[0][0]=0;
for(int i=1;i<=size;i++) {
m=len;
for(int j=0;j<m;j++) {
copy(data[j],a,data[j][0]);
a[0]++;
a[a[0]] = i;
copy(a,data[len],a[0]);
len++;
}
}
}
/*
* 求出所有的方案和最佳的方案
*/
static void knap(int w[],int v[],int W) {
int sumw,sumv,maxi = 0,maxsumw=0,maxsumv=0;
System.out.println("序号\t选中物品\t总重量\t总价值\t能够装入");
for (int i = 0; i < len; i++) {
System.out.print((i+1)+"\t");
sumw=sumv=0;
System.out.print("{");
for (int j = 1; j <= data[i][0]; j++) {
System.out.print(data[i][j]);
sumw+=w[data[i][j]-1];
sumv+=v[data[i][j]-1];
}
System.out.print("}\t"+sumw+"\t"+sumv);
if(sumw<=W) {
System.out.println("\t能");
if(sumv>maxsumv) {
maxsumw=sumw;
maxsumv=sumv;
maxi=i;
}
}
else
System.out.println("\t否");
}
System.out.print("最佳方案为:选中物品 {");
for (int i = 1; i <=data[maxi][0]; i++)
System.out.print(data[maxi][i]);
System.out.print("},总价值:"+maxsumw+",总价值"+maxsumv);
}
}
输出结果