美文网首页
背包问题

背包问题

作者: Stroman | 来源:发表于2018-03-14 11:03 被阅读18次

介绍

学习动态规划算法的经典例题。
动态规划算法一般有3个特征
1、最优化原理:最优解所包含的子问题的解也是最优的。
2、无后效性:就是后面问题的解决不引起前面问题解的变动,或者说不影响前面问题的解。
3、重叠子问题:就是说各子问题之间互相关联,即,以后问题的解可能会重复用到前面子问题的解。
另外,动态规划的输出往往依赖于链表的回溯。

思路

现在要达到的目的就是要求出在当前现有商品和背包容量的条件下如果才能使价值最高。
1、如果背包除了能装下当前物品外还有剩余容量的话,那么可以在刨去当前物品的情况下去找当背包容量等于这个剩余容量的值的时候的最优解。如果当前物品的价值+剩余容量的最优解优于刨去当前物品的当前背包容量的最优解的时候,那么当前物品在当前背包容量条件下的更优解就找到了。否则保持原样不变。
2、如果背包刚好能装下当前物品,那就直接跟刨去当前物品在当前背包容量条件下的最优解进行比较。如果优于这个最优解就更新在当前物品当前背包容量的前提下的最优解,否则保持不变。
3、根本装不下,于是直接保持原来最优解不变。

用法

package com.company;

public class Main {

    public static void main(String[] args) {
    // write your code here
        Good[] goodsArray = {
                new Good("水",10,3),
                new Good("书",3,1),
                new Good("食物",9,2),
                new Good("夹克",5,2),
                new Good("相机",6,1)
        };
        Good[] goodsArray0 = {
                new Good("吉他",1500,1),
                new Good("音响",3000,4),
                new Good("笔记本电脑",2000,3)
        };
        Bag.bagSolution(goodsArray,6);
    }
}

输出

解集:
0   0   10  10  10  10  
3   3   10  13  13  13  
3   9   12  13  19  22  
3   9   12  14  19  22  
6   9   15  18  20  25  
背包中物品价值最高为:25
相机  价值:6    重量:1
食物  价值:9    重量:2
水   价值:10   重量:3

Process finished with exit code 0

实现

package com.company;

public class Bag {
    /**
     * 动态规划算法最著名的背包问题
     * 每次装背包时只需要知道当背包重量排除某物品时
     * 加上余下空余重量的最优解才能得到当前的解。
     * 如果当前的解比已经得到同重量背包解更优就更新改重量背包的最优解。
     * 比较麻烦的是列举出背包中有哪些物品。
     * 也是用单链表,如果某单元格并不添加新物品则指针指向上面的单元格。
     * 否则指向左上边对应的单元格
     * 但是第一行要特殊处理。
     * @param goodsArray
     * @param bagSize
     */
    static public void bagSolution(Good[] goodsArray,int bagSize) {
        if (bagSize <= 0 || goodsArray.length <= 0) {
            System.out.println("无解");
            return;
        }
        BestSolution[][] answerArray = new BestSolution[goodsArray.length][bagSize];
        for (int counter = 0;counter < goodsArray.length;counter++)
            for (int counter0 = 0;counter0 < bagSize;counter0++)
                answerArray[counter][counter0] = new BestSolution();
        for (int counter = 0;counter < goodsArray.length;counter++) {
            for (int counter0 = 0;counter0 < bagSize;counter0++) {
                int remainingWeight = counter0 - goodsArray[counter].getWeight() + 1;
                if (remainingWeight > 0) {
                    //有剩余空间
                    if (counter - 1 >= 0) {
                        //如果不是第一行
                        if (answerArray[counter - 1][remainingWeight - 1].getMaxValue() + goodsArray[counter].getValue() > answerArray[counter - 1][counter0].getMaxValue()) {
                            answerArray[counter][counter0].goodPointer = goodsArray[counter];
                            answerArray[counter][counter0].prePointer = answerArray[counter - 1][remainingWeight - 1];
                            answerArray[counter][counter0].setMaxValue(answerArray[counter - 1][remainingWeight - 1].getMaxValue() + goodsArray[counter].getValue());
                        } else {
                            answerArray[counter][counter0].prePointer = answerArray[counter - 1][counter0];
                            answerArray[counter][counter0].setMaxValue(answerArray[counter - 1][counter0].getMaxValue());
                        }
                    } else {
                        //是第一行
                        answerArray[counter][counter0].goodPointer = goodsArray[counter];
                        answerArray[counter][counter0].setMaxValue(goodsArray[counter].getValue());
                    }
                } else if (remainingWeight == 0){
                    //刚好装下
                    if (counter - 1 >= 0) {
                        if (goodsArray[counter].getValue() > answerArray[counter - 1][counter0].getMaxValue()) {
                            answerArray[counter][counter0].goodPointer = goodsArray[counter];
                            answerArray[counter][counter0].setMaxValue(goodsArray[counter].getValue());
                        } else {
                            answerArray[counter][counter0].prePointer = answerArray[counter - 1][counter0];
                            answerArray[counter][counter0].setMaxValue(answerArray[counter - 1][counter0].getMaxValue());
                        }
                    } else {
                        answerArray[counter][counter0].goodPointer = goodsArray[counter];
                        answerArray[counter][counter0].setMaxValue(goodsArray[counter].getValue());
                    }
                } else {
                    //根本装不下
                    if (counter - 1 >= 0) {
                        answerArray[counter][counter0].prePointer = answerArray[counter - 1][counter0];
                        answerArray[counter][counter0].setMaxValue(answerArray[counter - 1][counter0].getMaxValue());
                    }
                }
            }
        }
        System.out.println("解集:");
        for (int counter = 0;counter < goodsArray.length;counter++) {
            for (int counter0 = 0;counter0 < bagSize;counter0++) {
                System.out.print(answerArray[counter][counter0].getMaxValue() + "\t");
            }
            System.out.println();
        }
        System.out.println("背包中物品价值最高为:" + answerArray[goodsArray.length - 1][bagSize - 1].getMaxValue());
        BestSolution headPointer = answerArray[goodsArray.length - 1][bagSize - 1];
        while (headPointer != null) {
            if (headPointer.goodPointer != null)
                System.out.println(headPointer.goodPointer.getGoodName() + "\t价值:" + headPointer.goodPointer.getValue() + "\t重量:" + headPointer.goodPointer.getWeight());
            headPointer = headPointer.prePointer;
        }
    }
}

package com.company;

public class BestSolution {
    public Good goodPointer = null;
    public BestSolution prePointer = null;
    private int maxValue = 0;

    public BestSolution() {
    }

    public int getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
    }
}

package com.company;

public class Good {
    private String goodName;
    private int value;
    private int weight;
    public Good nextPointer = null;

    public Good(String goodName, int value, int weight) {
        this.goodName = goodName;
        this.value = value;
        this.weight = weight;
    }

    public String getGoodName() {
        return goodName;
    }

    public int getValue() {
        return value;
    }

    public int getWeight() {
        return weight;
    }
}

相关文章

  • 背包问题(完全背包)

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题3——背包问...

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 背包问题

    0-1背包问题 问题 n个物体,它们各自有重量和价值,给定一个有容量的背包,如何让背包里装入的物体价值总和最大? ...

  • 背包问题

    问题描述 假如有一个能装下4磅的背包,如何从下列商品列表中选择商品填充背包,使价值达到最大: 动态规划 要解决背包...

  • 背包问题

    (1)0-1背包容量为10的背包,有5种物品,每种物品只有一个,其重量分别为5,4,3,2,1,其价值分别为1,2...

  • 背包问题

  • 背包问题

    01背包(物品只有一个) 有N件物品和一个容量为V的背包。第i建物品的费用是w[i],价值是v[i]。求解将哪些物...

  • 背包问题

    1. 01背包 状态说明:背包体积为v,物品个数为n,f[n,v]表示前n件物品加入背包的最大价值。c_i,w_i...

  • 背包问题

    01背包 优化空间复杂度,变为一维; 外循环依然是n从1->N, 注意内循环 v是从V->0,为什么内循环是V->...

  • 背包问题

    介绍 学习动态规划算法的经典例题。动态规划算法一般有3个特征1、最优化原理:最优解所包含的子问题的解也是最优的。2...

网友评论

      本文标题:背包问题

      本文链接:https://www.haomeiwen.com/subject/huaxqftx.html