zoukankan      html  css  js  c++  java
  • 01背包问题

    public class Main {
        
        /**
         * 
         * @param value
         * @param weight
         * @param c 背包容量
         * @param m m(i,j)背包容量为j,可选择物品为i,i+1,...,n时背包的最优值
         */
        public static void knapsack(int[] value, int[] weight, int c, int[][] m){
            int n = value.length - 1;
            
            // 初始化:只选第n个物品的时候,背包容量范围的各个值的所选物品的最优值
            int jMax = Math.min(weight[n], c);
            for (int j = 0; j <= jMax; j++) {
                m[n][j] = 0;
            }
            for (int j = weight[n]; j < c; j++) {
                m[n][j] = value[n];
            }
            
            // 可选物品为i,i+1,...,n-1,背包容量范围各个值的所选物品的最优值
            for (int i = n - 1; i > 0; i--) {
                jMax = Math.min(weight[i], c);
                for (int j = 0; j < jMax; j++) {
                    m[i][j] = m[i + 1][j];
                }
                for (int j = weight[i]; j < c; j++) {
                    m[i][j] = Math.max(m[i + 1][j], m[i + 1][j - weight[i]] + value[i]);
                }
            }
            
            // 可选物品为1,2,...,n,背包容量为c的所选物品的最优值
            m[0][c] = m[1][c];
            if(c > weight[0]){
                m[0][c] = Math.max(m[0][c], m[1][c - weight[0]] + value[0]);
            }
        }
        
        /**
         * 获取最优解
         * @param m
         * @param weight
         * @param c
         * @param x
         */
        public static void traceback(int[][] m, int[] weight, int c, int[] x){
            int n = weight.length - 1;
            for (int i = 0; i < n; i++) {
                if(m[i][c] < m[i + 1][c]){
                    x[i] = 0;
                }else{
                    x[i] = 1;
                    c -= weight[i];
                }
            }
            
            x[n] = m[n][c] > 0 ? 1: 0;
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            int c = 10;
            int[] weight = {5, 5, 5};
            int[] value = {10,5,11};
            
            int[][] m = new int[weight.length][c + 1];
            knapsack(value, weight, c, m);
            
            int[] x={0,0,0};
            traceback(m, weight, c, x);
            
            System.out.println("最优值为:" + m[0][c]);
            
            System.out.print("最优解为:");
            for (int i = 0; i < x.length; i++) {
                System.out.print(x[i] + ((i != x.length - 1)? ",":""));
            }
            System.out.println("
    ");
            
            System.out.println("最优值矩阵为:");
            for (int i = 0; i < weight.length; i++) {
                for (int j = 0; j < c + 1; j++) {
                    System.out.print(m[i][j] + ((j != c) ? "," :""));
                }
                System.out.print("
    ");
            }
        }
    
    }

    结果为:

    最优值为:21
    最优解为:1,1,0

    最优值矩阵为:
    0,0,0,0,0,0,0,0,0,0,21
    0,0,0,0,0,11,11,11,11,11,0
    0,0,0,0,0,11,11,11,11,11,0

  • 相关阅读:
    AutoLISP 绘制滚轮
    铁打的学校流水的学生
    AutoLISP绘制花型三
    AutoCAD LISP花型图案二
    AutoCAD LISP多边形边为直径绘制圆
    AutoCAD矩形交叉口框短边切圆一
    AutoCAD LISP花型图案一
    AutoLISP圆形堆栈金字塔
    AutoCAD矩形交叉口框短边切圆二
    AutoCADLISP绘制楼梯
  • 原文地址:https://www.cnblogs.com/kelin1314/p/4320107.html
Copyright © 2011-2022 走看看