您的位置:首页 > 其它

动态规划_0-1背包问题

2016-12-19 18:02 281 查看
/**
* 动态规划_0-1背包问题
* @author Matt
*/
public class Knapsack {

/**
* 求得最优值
* @param v 物品价值数组
* @param w 物品质量数组
* @param c 背包容量
* @param m 最优值数组
*/
public static void knapsack(int []v, int []w, int c, int [][]m) {
int n = v.length - 1; // 物品的数量
// 先对最后一个物品进行取舍,得到基础值
// 将最后一个物品的质量和背包容量进行比较,取较小值
int jMax = Math.min(w
-1, c);
for (int j = 0; j <= jMax; j++) { // 背包容量小于物品质量则不装入
m
[j] = 0; // 不装入则价值为0
}
for (int j = w
; j <= c; j++) { // 物品质量大于背包质量则装入
m
[j] = v
; // 装入则价值为当前物品的价值v

}
// 对2~n-1个物品进行判断选取
for (int i = n - 1; i > 1; i--) {
jMax = Math.min(w[i]-1, c);
// 背包容量小于当前物品的质量则不装入
for (int j = 0; j <= jMax; j++) {
m[i][j] = m[i+1][j];
}
// 背包容量大于当前物品的质量
for (int j = w[i]; j <= c; j++) {
// 对不装入和装入的两种情况取价值高者
m[i][j] = Math.max(m[i+1][j], m[i+1][j-w[i]] + v[i]);
}
// 最后对第一个物品进行取舍
m[1][c] = m[2][c];
if (c >= w[1]) {
// 求得的m[1][c]即为最优值
m[1][c] = Math.max(m[1][c], m[2][c-w[1]] + v[1]);
}
}
}

/**
* 最优解路径
* @param m 最优值数组
* @param w 质量数组
* @param c 背包容量
* @param x 是否拿取数组
*/
public static void traceback(int [][]m, int []w, int c, int []x) {
int n = w.length - 1; // 物品的个数
// 对m数组从第一个物品到n-1个物品进行遍历
for (int i = 1; i < n; i++) {
// 如果没有装取,x[i]置0表示没有装取
if (m[i][c] == m[i+1][c]) x[i] = 0;
else { // 只有两种情况,不装或装,x[i]置1表示装取物品
x[i] = 1;
c -= w[i]; // 装取则容量减去当前物品的质量
}
x
= (m
[c] > 0) ? 1 : 0; // 对最后一个物品进行判断
}
}

public static void main(String[] args) {
int []v = {0, 6, 3, 5, 4, 6};
int []w = {0, 2, 2, 6, 5, 4};
int c = 10;
int [][]m = new int[7][11];
int []x = new int[7];
knapsack(v, w, c, m);
traceback(m, w, c, x);
System.out.println("Value: " + m[1][c]);
System.out.print("Trace: ");
for (int i = 0; i < x.length; i++) {
System.out.print(x[i]);
}
}
}
// 运算结果:
//  Value: 15
//  Trace: 0110010
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: