White Road algorithm of (a) ---- 01 knapsack

Foreword

Thought about this issue before, to no avail reflect the old way: online help
after browsing numerous blog, have some ideas on this record. As the study notes only
if wrong, excuse me point out that you, your advice is my pleasure.

Note: The main reference since this is a blog , which is also a blog

solution

Title:
Suppose cave total e, d, c, b, a treasure five (5 kinds of treasures not), their weights are 4,5,6,2,2, their value are 6,4, 5,3,6, and now to give you the backpack load to 10, how loaded backpack can to take away most of the wealth?

Thinking

Here by Vi represents a value of the i-th item; the Wi represents the i-th weight of the item;
F. (I, j) represents the current , selection can be reached from the i-th item in the sequence knapsack capacity j when the maximum value
the third example refers to articles c, and so on.

Add a new item into the backpack when there are two options:

  • New items added weight greater than the current capacity of the backpack, naturally we can not be added to the backpack;
  • By weight of the newly added article is smaller than the current capacity of the backpack, so we can choose a new item added to a backpack or choose not to join backpack.

NOTE: The following examples are independent of the subject mentioned above cited front.

The first option

In the first case, the weight of the newly added article is greater than the current capacity of the pack, it is not necessary to change the sequence of the original article backpack (e.g., the original sequence of articles: a, b), namely: after encountering a new article, which value remains V (a) + V (b ) , we can convert it into: yES in the face of an i-th items: F. (i, J) = F. (i-. 1, J); (PS: this is a assignment)
For example:
in the case where the capacity of the backpack 5, backpack has two items: a, b; when faced with the third item C, which was found greater than the current weight of the backpack weight (Wc> 5), so there are F (3,5) = F (2,5 )
can be drawn: when Wi> j; with a F (i, j) = F (i-1, j)

The second option

In the second case, the weight of items newly added backpack less than the current capacity, we are faced with a choice: Do you want to change into a backpack
Change and do not change:
For example, in the case of a capacity of 9 backpack, backpack this time there are three items: a, b, c; this time it encounters the first four items d, to change into, in fact, another idea is that we tacitly: in capacity 9 is a case where, from a, b, c, d four articles selected item in the sequence with the highest value has a certain d, but whether it is after the shift into the highest value, and also need to be Va + Vb + Vc comparison (in fact, F. (. 1-I, J) )
That is: when Wi <= j when there is: F (i, j) = max {F (i-1, j), F (i-1, j- the Wi) + Vi}
F (i-1, J) is the highest value obtained without change of
F (i-1, j- Wi) + Vi means that if we change the default which is to achieve the highest value most excellent sequence one after into d, backpack capacity of j-Wi, but this time there was a new problem a: original backpack in a, b, c if it does not need to make changes? This is something we do not know, that can only be calculated.
But for the problem A, we are not able to understand: In the case of backpack capacity of j-Wi, how to choose from the a, b, c three items in order to achieve the highest value (regardless of whether all hold a, b , c), then how do we get optimal sequence backpack capacity of j-Wi is it? Will be announced ...

Dynamic Programming

The table of FIG: top row for the "current" Capacity Backpack (j), the first column represents the sequence item (i)
, for example: e (i = 1), d (i = 2), c (i = 3), b (i = 4), a (i = 5)
Note: The following example will be: c-1, 3-1 = 2 in fact, also refers to d

1 2 3 4 5 6 7 8 9 10
e 0 0 0 6 6 6 6 6 6 6
d 0 0 0 6 6 6 6 6 10 10
c 0 0 0 6 6 6 6 6 10 11
b 0 3 3 6 6 9 9 9 10 11
a 0 6 6 9 9 12 12 15 15 15

How to understand this form it ??
E row table from one cell to the succeeding column to fill.
B-th row 0 represents: when the backpack capacity of 1, from e, d, c, b four kinds of items to choose how to achieve the highest value?
The d-line 7 represents: when the backpack capacity of 7, from how to choose e, d two goods in order to achieve the highest value?
.
.
.
Based on this table,
for example, when we calculate the row c 8 column when:
Wc of <J; F. (C, J) = max {F. (C-. 1, J), F. (C-. 1, J-Wc of) + Vc of }
namely:
. 6 <. 8; F. (3,8) = max {F. (2,8), F. (2,8-6) +5}
= "F. (3,8) = max {F. (2, . 8), F. (2,2 &) +5}
= "F (3,8) = max {6,0} +. 5
. 6 =" F (3,8) =
previously we calculate F (3,8) we have calculated the F (2,2), it can be directly referenced. This is the solution to the problem of A.

Note: The
dynamic programming method to solve the carefully structured sequence, to solve the problem only once for each child, and saved the result. If the solution to this problem child then again, only to find the saved results without having to recalculate. Therefore, the dynamic programming algorithm is to give additional memory space to save computing time, is a typical example of space-time trade-off. ----- "Introduction to Algorithms"

Subject code implementation


/**
 * 使用动态规划解决01背包问题
 */
public class finalDemo01 {

    /**
     * 假设山洞里共有e d c b a这5件宝物(不是5种宝物),它们的重量分别是4,5,6,2,2,它们的价值分别是6,4,5,3,6
     * 现在给你个承重为10的背包, 怎么装背包,可以才能带走最多的财富
     *
     * @param args
     */

    public static void main(String[] args) {
        //定义矩阵
        //假设有5个物品e d c b a背包容量为10
        //其重量分别为:4,5,6,2,2
        //价值为:6,4,5,3,6
        //定义价值矩阵,横坐标为背包的容量
        int[][] valueMartix = new int[6][11];
        //为了方便后面的取值,将没有意义的行列置0,这样取值就不必考虑行列为0的情况
        for (int a = 0; a < 11; a++) {
            valueMartix[0][a] = 0;
        }
        for (int a1 = 0; a1 < 5; a1++) {
            valueMartix[a1][0] = 0;
        }


        //定义物品的重量数组
        int[] weight = {0, 4, 5, 6, 2, 2};
        //定义价值数组
        int[] value = {0, 6, 4, 5, 3, 6};

        int capacity = 10;
        //开始填写价值矩阵
        int i = 1;
        int j = 1;


        while (j <= capacity) {
            for (; i < weight.length; i++) {
                if (j < weight[i]) {
                    valueMartix[i][j] = valueMartix[i - 1][j];
                } else {
                    valueMartix[i][j] = max(valueMartix[i - 1][j], valueMartix[i - 1][j - weight[i]] + value[i]);
                }
            }
            i = 1;
            j++;
        }
        //输出最佳方案对应的最大价值
        System.out.println(valueMartix[5][10]);
    }

    public static int max(int v1, int v2) {
        if (v1 >= v2) {
            return v1;
        } else {
            return v2;
        }
    }
}

Total code implementation

Further expansion:


/**
 * 最终版本,删减了一些不必要的注释
 * 使用动态规划方法解决01背包问题
 * 自底向上
 */
public class finalDemo02 {


    public static void main(String[] args) {

        //定义货物的数量
        int goodsNumber;
        //定义背包的容量
        int capacity;

        //输入货物的数量和背包的总容量
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入货物的数量");
        goodsNumber = sc.nextInt();
        System.out.print("请输入背包的总容量");
        capacity = sc.nextInt();

        //定义矩阵
        //定义价值矩阵,横坐标为背包的容量
        int[][] valueMartix = new int[goodsNumber + 1][capacity + 1];
        //为了方便后面的取值,将没有意义的行列置0,这样取值就不必考虑行列为0的情况
        for (int a = 0; a < capacity; a++) {
            valueMartix[0][a] = 0;
        }
        for (int a1 = 0; a1 < goodsNumber; a1++) {
            valueMartix[a1][0] = 0;
        }

        //定义重量数组
        List weight = new ArrayList();
        //定义价值数组
        List value = new ArrayList();

        //将首为置为0
        weight.add(0);
        value.add(0);


        //用户输入货物的重量和其对应的价值
        for (int goods = 1; goods <= goodsNumber; goods++) {
            //输入重量
            weight.add(sc.nextInt());
            //输入价值
            value.add(sc.nextInt());
        }


        //开始填写价值矩阵
        int i = 1;
        int j = 1;

        while (j <= capacity) {
            for (; i < weight.size(); i++) {
                if (j < (Integer) weight.get(i)) {
                    valueMartix[i][j] = valueMartix[i - 1][j];
                } else {
                    valueMartix[i][j] = max(valueMartix[i - 1][j], valueMartix[i - 1][j - (Integer) weight.get(i)] + (Integer) value.get(i));
                }
            }
            i = 1;
            j++;

        }

        myPrint(valueMartix,goodsNumber,capacity);
    }

    //比较换与不换两种情况下的价值,返回价值高的数字
    public static int max(int v1, int v2) {
        if (v1 >= v2) {
            return v1;
        } else {
            return v2;
        }
    }
    //输出最佳方案能得到的最大价值
    public static void myPrint(int[][] valueMartix,int goodsNumber,int capacity){
        System.out.println(valueMartix[goodsNumber][capacity]);
    }

}
Published 10 original articles · won praise 3 · Views 309

Guess you like

Origin blog.csdn.net/weixin_41043607/article/details/104804216