1 背包问题
有N(4)件物品和一个容量为V( BeiBaoSpace = 8)的背包。第i件物品的占用空间是space,价值是value。求解将哪些物品装入背包可使价值总和最大。
抽象模型如下:
2 java 代码实现
import com.google.common.collect.Lists;
import lombok.Data;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class BeiBao {
private static final int BeiBaoSpace = 8;
private static final int ProductCount = 4;
private static List<Product> products = Lists.newArrayList(
new Product(1,2,3),
new Product(2,3,4),
new Product(3,4,5),
new Product(4,5,6)
);
private static Map<Integer, Product> productMap;
static {
productMap = products.stream().collect(Collectors.toMap(Product::getNo, Function.identity()));
}
private static int[][] OPTIMAL_VALUE_ARRAY = new int[5][9];
public static void main(String[] args) {
// 构造最优矩阵
for (int row = 0; row <= ProductCount; row++) {
for (int space = 0; space <= BeiBaoSpace; space++) {
if (row == 0 || space == 0) { // 不放任何产品 或者 空间为0
OPTIMAL_VALUE_ARRAY[row][space] = 0;
continue;
}
// 总空间都不足放 编号为 row 的产品, 则和放row-1产品的最优价值一样,不放
if (space < productMap.get(row).getSpace()) {
OPTIMAL_VALUE_ARRAY[row][space] = OPTIMAL_VALUE_ARRAY[row - 1][space];
continue;
}
Product product = productMap.get(row);
// 如果总空间充足,比较放和不放的最优解;
// 1 不放时最优解
int unOfferValue = OPTIMAL_VALUE_ARRAY[row - 1][space];
// 2 放的话 腾空最优值;
int offerValueSubCurProduceSpace = findValueBySpace(OPTIMAL_VALUE_ARRAY, space - product.getSpace(), row);
if ((offerValueSubCurProduceSpace + product.getValue()) > unOfferValue) {
OPTIMAL_VALUE_ARRAY[row][space] = offerValueSubCurProduceSpace + product.getValue();
} else {
OPTIMAL_VALUE_ARRAY[row][space] = unOfferValue;
}
}
}
// 输出最优矩阵
for (int row = 0; row <= ProductCount; row++) {
for (int space = 0; space <= BeiBaoSpace; space++) {
System.out.print(OPTIMAL_VALUE_ARRAY[row][space]);
System.out.print(" ");
}
System.out.println(" ");
}
// 输出最优解产品
int space = BeiBaoSpace;
for (int row = ProductCount; row > 0 ; row--) {
Product product = productMap.get(row);
// 判断该productNo = row 是否放到背包中,判断相同空间 row 和 row-1 产品的最优价值是否相同
if(OPTIMAL_VALUE_ARRAY[row][space] != OPTIMAL_VALUE_ARRAY[row-1][space]){
System.out.println("产品 productNo = " + row + " 放入背包");
space = space - product.getSpace();
}
if (space <= 0){
break;
}
}
}
private static int findValueBySpace(int[][] optimalValueArray, int space, int maxRow) {
int max = 0;
for(int i = 0; i < maxRow; i++){
if(max < optimalValueArray[i][space]){
max = optimalValueArray[i][space];
}
}
return max;
}
@Data
public static class Product{
private int no;
private int space;
private int value;
public Product(int no, int space, int value) {
this.no = no;
this.space = space;
this.value = value;
}
}
}
3 输出结果