标签:背包
先来个0-1背包问题,设置背包总共能容纳的重量是100kg,当前给定有5个物品,它们的重量和价值分别存在数组w和v上(注意:为了方便,我把这两个数组的第一位的值设为0,即实际数组大小为6),并存储了每个物品是否被装包的情况,我们先来看他的Java实现。
package com.algorithm.impl; import java.util.Arrays; public class Knapsack { public static void main(String[] args){ int[] w = {0, 25, 40, 10, 48, 27}; int[] v = {0, 32, 45, 21, 53, 40}; int res = knapsack(100, w, v); System.out.println("包的最大价值为: " + res); } public static int knapsack(int maxw, int[] w, int[] v){ int num = w.length - 1; //保存结果 int[][] f = new int[num + 1][maxw + 1]; //保存每个物体是否装包 int[][] s = new int[num + 1][maxw + 1]; for(int i = 0; i < f.length; i++) Arrays.fill(f[i], 0); //物品种类为num for(int n = 1; n <= num; n++){ //设置可接受的重量值 for(int x = 1; x <= maxw; x++){ //设置对于物品n可以最多容纳多少个,因为这是0-1背包,所以非1即0,这是通过重量而得出的 int maxn = 1; if(w[n] > x) maxn = 0; for(int i = 0; i <= maxn; i++){ //如果当前的结果可以使背包有更高的价值,那么添加上去 if(f[n][x] < f[n - 1][x - w[n] * i] + i * v[n]){ f[n][x] = f[n - 1][x - w[n] * i] + i * v[n]; s[n][x] = i; } } } } int result = 0; int xx = 0; //获取最大值 for(int i = 0; i <= maxw; i++){ if(f[num][i] > result){ result = f[num][i]; xx = i; } } //输出每种物品是否装包的情况 for(int i = num; i >= 1; i--){ System.out.println("物品" + i +": " + s[i][xx]); xx -= s[i][xx] * w[i]; } return result; } }
物品5: 1 物品4: 1 物品3: 0 物品2: 0 物品1: 1 包的最大价值为: 125
物品编号 体积 (cm3) 重量 (KG) 数量 价值
1 30 3 10 4
2 50 8 10 5
3 10 2 10 2
4 23 5 8 3
5 130 20 5 11
package com.algorithm.impl; import java.util.Arrays; public class Knapsack02 { public static void main(String[] args){ int[] v = {0, 30, 50, 10, 23, 130}; //体积 int[] w = {0, 3, 8, 2, 5, 20}; //重量 int[] c = {0, 10, 10, 10, 8, 5}; //数量 int[] t = {0, 4, 5, 2, 3, 11}; //价值 int res = knapsack(500, 100, v, w, c, t); System.out.println("包的最大价值为: " + res); } public static int knapsack(int maxx, int maxy, int[] v, int[] w, int[] c, int[] t){ int num = v.length - 1; //保存结果 int[][][] f = new int[num + 1][maxx + 1][maxy + 1]; //保存每个物体的装包数量 int[][][] s = new int[num + 1][maxx + 1][maxy + 1]; for(int i = 0; i < f.length; i++) for(int j = 0; j < f[i].length; j++) Arrays.fill(f[i][j], 0); for(int i = 0; i < s.length; i++) for(int j = 0; j < s[i].length; j++) Arrays.fill(s[i][j], 0); //物品种类为num for(int n = 1; n <= num; n++){ //设置可接受的体积 for(int x = 1; x <= maxx; x++){ //设置可接受的重量 for(int y = 1; y <= maxy; y++){ //设置对于物品n可以最多容纳多少个,这是通过体积和重量的双重限制而得出的 int maxn = c[n]; if(x / v[n] < maxn) maxn = x / v[n]; if(y / w[n] < maxn) maxn = y / w[n]; for(int i = 0; i <= maxn; i++){ //如果当前的结果可以使背包有更高的价值,那么添加上去 if(f[n][x][y] < f[n - 1][x - v[n] * i][y - w[n] * i] + i * t[n]){ f[n][x][y] = f[n - 1][x - v[n] * i][y - w[n] * i] + i * t[n]; s[n][x][y] = i; } } } } } int result = 0; int xx = 0, yy = 0; //获取最大值 for(int i = 0; i <= maxx; i++){ for(int j = 0; j <= maxy; j++){ if(f[num][i][j] > result){ result = f[num][i][j]; xx = i; yy = j; } } } //输出每种物品的装包数量 for(int i = num; i >= 1; i--){ int temp = s[i][xx][yy]; System.out.println("物品" + i +"的数量为: " + s[i][xx][yy]); xx -= temp * v[i]; yy -= temp * w[i]; } return result; } }运行结果为:
物品5的数量为: 0 物品4的数量为: 4 物品3的数量为: 10 物品2的数量为: 0 物品1的数量为: 10 包的最大价值为: 72
标签:背包
原文地址:http://blog.csdn.net/hjiam2/article/details/39052041