问题描述
n个物品和1个背包。对物品i,其价值为vi,重量为 wi,其价值为vi,背包容量为W。如何选取物品装入背包,使背包中所装入的物品的总价值最大?
数据结构的选择
数组w[n]来存放n个物品的重量;
数组v[n]来存放n个 物品的价值;
背包重量为W,
数组m[n+1][W+1]存放每次迭代执行结果;
数组x[n]用来存放所装入背包的物品状态
算法实现与测试
代码实现
package backpack;
import java.util.Scanner;
public class Backpack {
/**
* 动态规划算法实现
* @param v 存放n个 物品的价值数组
* @param w 存放n个物品的重量数组
* @param W 背包容量
* @param m 存放每次迭代执行结果
*/
public static void knapsack(int[] v,int[] w,int W,int[][] m) {
int n = v.length;
//装入为0,初始化
for(int i = 0;i < n + 1;i++)
m[i][0] = 0;
//背包内没有物品时初始化
for(int j = 0;j < W + 1;j++)
m[0][j] = 0;
for(int i = 1;i<n + 1;i++) {
for(int j=1;j<W + 1;j++) {
if(j<w[i-1])
m[i][j]=m[i-1][j];
else
m[i][j]=Math.max(m[i-1][j], m[i-1][j-w[i-1]]+v[i-1]);
}
}
}
/**
* 计算最优解
* @param w
* @param W
* @param m
* @param x 存放所装入背包的物品状态的最优解
*/
public static void traceback(int[] w,int W,int[][] m,int[] x) {
int n = w.length;
int j = W;
for(int i = n;i > 0;i--) {
if(m[i][j] == m[i-1][j])
x[i - 1] = 0;
else {
x[i - 1] = 1;
j-=w[i - 1];
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入背包容量(整数):");
System.out.print("W:");
Scanner readr = new Scanner(System.in);
int W = readr.nextInt();
System.out.println("物品数量:");
System.out.print("I:");
int I = readr.nextInt();
int[] v = new int[I];
int[] w = new int[I];
System.out.println("请依次输入"+I+"个物品的重量:");
for(int i = 0;i < I;i++)
v[i] = readr.nextInt();
System.out.println("请依次输入"+I+"个物品的价值:");
for(int i = 0;i < I;i++)
w[i] = readr.nextInt();
int[][] m = new int[I+1][W+1];
knapsack(v,w,W,m);
for(int i = 0;i < I + 1;i++) {
for(int j = 0;j < W + 1;j++)
{
System.out.print(m[i][j]+" ");
}
System.out.println();
}
int[] x = new int[I];
traceback(w,W,m,x);
System.out.println("最优解序列:");
for(int i = 0 ;i < I;i++)
System.out.print(x[i]+" ");
}
}
来源:CSDN
作者:MP-214
链接:https://blog.csdn.net/BennetMa/article/details/103242306