回溯法:
Knapsack.java
public class Knapsack {
private double c; //背包重量
private int n; //物品数量
private double[] w; //物品重量
private double[] v; //物品价值
private int[] num; //物品序号
private double cw; //当前背包重量
private double cv; //当前背包价值
private double maxv; //当前最优值
private int[] bestx; //当前最优解
private int[] x; //部分解
public Knapsack(double[] weight, double[] value, double c){
this.c =c;
this.n = weight.length;
w = new double[n];
v = new double[n];
num = new int[n];
for(int i = 0; i < n; i++) {
num[i] = i + 1;
w[i] = weight[i];
v[i] = value[i];
}
//将各物品按单位重量价值从大到小排序(排序)
double tmp;
int tmpp;
for(int i = 0; i < n; i++) {
for(int j = 1; j < n; j++) {
if((v[j] / w[j]) > (v[j-1] / w[j-1])) {
tmp = v[j-1];
v[j-1] = v[j];
v[j] = tmp;
tmp = w[j-1];
w[j-1] = w[j];
w[j] = tmp;
tmpp = num[j-1];
num[j-1] = num[j];
num[j] = tmpp;
}
}
}
}
void cacu() {
cw = 0;
cv = 0;
maxv = 0;
bestx = new int[n];
x = new int[n];
backtrack(0);
System.out.print("装入背包的总价值:");
System.out.println(maxv);
System.out.print("装入背包的物品序号:");
for(int i=0; i < n; i++) {
if(bestx[i] == 1) {
System.out.print(num[i] + " ");
}
}
}
void backtrack(int t) {
if(t >= n) {
output(x);
return;
}
for(int i=1; i>=0; i--) {
x[t] = i;
if(i == 1) {
cw += w[t];
cv += v[t];
if(constraint(t)&&bound(t)) {
backtrack(t+1);
}
cw -= w[t];
cv -= v[t];
}
if(i == 0) {
if(constraint(t)&&bound(t)) {
backtrack(t+1);
}
}
}
}
void output(int[] x) {
for(int i = 0; i < n; i++) {
bestx[i] = x[i];
}
maxv = cv;
}
boolean constraint(int t) {
if(c < cw) return false;
return true;
}
boolean bound(int t) {
double cwr = cw;
double cvr =cv;
while(t < n-1 && (w[t+1] <= (c-cwr))) {
cwr += w[t+1];
cvr += v[t+1];
t++;
}
if(cvr <= maxv) return false;
return true;
}
}
Test.java
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
double c = 50;
int n = 0;
Scanner sc = new Scanner(System.in);
System.out.print("输入背包容量:");
c = sc.nextDouble();
System.out.print("输入物品数量:");
n = sc.nextInt();
double[] w = new double[n];
double[] v = new double[n];
for(int i=1; i<=n; i++){
System.out.print("输入物品" + i + "质量和价值:");
w[i-1] = sc.nextDouble();
v[i-1] = sc.nextDouble();
}
Knapsack x = new Knapsack(w, v, c);
long start = System.nanoTime();
x.cacu();
long end = System.nanoTime();
System.out.println();
System.out.println("花费时间: " + String.valueOf(end - start) + "纳秒");
}
}