【01背包问题】java 实现源码,解题思路

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 输出结果

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页