背包问题

package com.algorithm.背包问题;

public class BeiBaoProblem {
    public static void main(String[] args){
        int[] v = new int[]{6,3,5,4,6};
        int[] w = new int[]{2,2,6,5,4};
        int n = v.length, c = 10;
        /*
         * m的维数为(n+1)*(c+1)
         */
        int[][] m = knapsack(v, w, c, n);
        for(int i = 0; i <= n; i++){
            for(int j = 0; j<= c; j++)
                System.out.print(m[i][j]+" ");
            System.out.println();
        }
        System.out.println("背包问题的最优解:"+m[n][c]);
        System.out.println("背包容量:"+c);
        int x[] = traceBack(m,w,c,n);
        for(int k = 0; k < x.length; k++)
            if(x[k] == 1)
                System.out.println("第"+ (k+1) +"个物品 "+"(价值"+v[k]+"、重量"+w[k]+") 装入");

    }

    /**
     * 
     * @param v 表示物品的价值
     * @param w 表示物品的重量 
     * @param c 表示背包容量
     * @param n 表示n种物品
     * @param m 存储m(i,j)的值,表示背包容量为j,可选择物品为i,i+1,...,n时背包问题的最优解
     */
    public static int[][] knapsack(int[] v, int[] w, int c, int n){
        int[][] m = new int[n+1][c+1];
        /*
         * 背包容量为0的背包,不能装入第i个物品
         */
        for(int i = 0; i < n+1 ; i++)   m[i][0] = 0;
        /*
         * 背包容量为j的背包,不能装入前0个物品 
         */
        for(int j = 0; j < c+1; j++ ) m[0][j] = 0;
        /*
         * 分两种情况
         */
        for(int i = 1; i < n+1; i++){
            for(int j = 1; j < c + 1; j++)  
                /*
                 * 背包能够装入第i个物品,选择是否装入。取装入时,和不装入时的最大值
                 */
                if(w[i-1] <= j){
                    m[i][j] = Math.max(m[i-1][j], m[i-1][j-w[i-1]] + v[i-1]);
                }else{
                    /*
                     * 不装入第i个物品
                     */
                    m[i][j] = m[i-1][j];
                }
        }
        return m;
    }

    public static int[] traceBack(int m[][],int[] w, int c, int n){
        int[] x = new int[n+1];
        for(int i = 1; i < n+1; i++)
            if(m[i][c] == m[i-1][c]){
            /*
            *不装入第i个物品
            */
                x[i-1] = 0;
            }else{
            /*
            *装入第i个物品
            */
                x[i-1] = 1;
                /*
                *背包容量减少w[i-1]
                */
                c -= w[i-1];
            }
        return x;
    }
}

运行效果:

0 0 0 0 0 0 0 0 0 0 0 
0 0 6 6 6 6 6 6 6 6 6 
0 0 6 6 9 9 9 9 9 9 9 
0 0 6 6 9 9 9 9 11 11 14 
0 0 6 6 9 9 9 10 11 13 14 
0 0 6 6 9 9 12 12 15 15 15 
背包问题的最优解:15
背包容量:10
第1个物品 (价值6、重量2) 装入
第2个物品 (价值3、重量2) 装入
第5个物品 (价值6、重量4) 装入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值