[Dynamic Programming] knapsack problem

Problem Description

01 knapsack problem: There are n items, each item has a two volume and value of the property, there is now a fixed-capacity backpack, you want these items into a backpack, making the total value of the largest items in the backpack, and asked how to put?

Note: The number of each item is 1.

Set $ ​​V = 14 $.

For convenience of description, we use the $ c_1, c_2, c_3, .... c_n $ is the volume of goods, with $ w_1, w_2, w_3, .... w_n $ represents the value of goods, with $ V $ express backpack capacity, $ n $ is the number of items.

Dynamic Programming Description

Knapsack problem is a dynamic programming problem, and divide and conquer algorithm, as it is a big problem into a problem a little, and then locate the recursive problem between the big and small problems, will be combined into a small problem a big problem,

And usually require these small issues have optimal . Dynamic programming problem can be solved generally contain two properties: optimal substructure and overlapping sub-problems. Essentially dynamic programming method is exhaustive, but it than the general efficiency of the algorithm is higher,

This is because it can cut overlapping sub-problems, making the overall complexity is not so high.

 

Solution

1. recursive method

Let's start with the easiest place to start is to start with a recursive method to solve this problem.

First, for each item, we have only two choices: release or hold. We will all probably out of exhaustion, you can obtain the following tree diagram (only drew the first four nodes):

This tree, each branch can only choose one, each line represents a sub-issue. We use the $ F (i, v_i) $ represent ago $ i $ th largest value in the items into a backpack (that is, the optimal solution), then this $ v_i $ refers to the post before placing $ i $ a backpack items the remaining capacity.

Obvious $ F (5, v_5) $ is the big problem we have to be solved, the problem is that all of a sudden split: $ F (1, v_1) $, $ F (2, v_2) $, $ F (3, v_3) $, $ F (4, v_4) $ . To solve this big problem, we have to first solve its problem child in front of a $ F (4, v_4) $ ( solving the original problem but also sub-optimal problem, so the problem has optimal substructure , which is judged can the problem with one of the conditions of dynamic programming solution).

As for why to solve the $ F (5, v_5) must first solve the $ F (4, v_4) $ $ issue before, this is a problem because for $ F (5, v_5) $, if solved the problem of $ F (4, V_4) $ rest only need a final determination whether the article is greater than the volume remaining capacity of the backpack, the backpack is directly into, or to hold.

As for the sub-problem $ F (4, v_4) $, we have to solve the $ F (3, v_3) $ .... thus have to deal with $ F (1, v_1) $. For the sub-question $ F (1, v_1) $, because there is no problem child in front of it, so it only needs to solve the judge $ c_1 \ le V $ holds.

So for each sub-issue, because the front of the sub-problems have been resolved, so we only need to do two choices: release, or hold.

Suppose we already know before the $ i-1 $ items into a backpack optimal solution $ F (i-1, v) $, then $ i $ for the first item to be placed in a backpack there are three cases:

   If the volume of the article is greater than $ $ C_i backpack remaining capacity of $ v $, it can be discarded article:

     $F(i, v_i) = F(i-1, v_i-1)$

   Otherwise, there are two options:

   1. $ I $ a hold of the article:

    $F(i, v_i) = F(i-1, v_i-1)$

   2. Place the first $ i $ th items:

    $F(i, v_i) = w_i + F(i-1, v_i-1-c_i)$

To select the maximum total value of these two scenarios, so:

$$
F(i, v_i) =
\begin{cases}
F(i-1, v_{i-1}), & \text{ $c_i > v_{i-1}$ } \\
max(F(i-1, v_{i-1}), w_i +F(i-1, v_{i-1}-c_i)), & \text{ $c_i \le v_{i-1}$ }
\end{cases}
$$

 用Python实现代码如下:

#递归求解
def rec_bag(c, w, v, i):
    '''
    param c: 物品体积
    param w: 物品价值
    param v: 当前背包剩余容量
    param i: 当前物品编号
    return: 背包装下物品的最大价值
    '''
    if i > len(c)-1:
        return 0
    elif v <= 0: #体积不能为负
        return 0
    elif v > 0:
        if c[i] <= v:
            A = w[i] + rec_bag(c, w, v-c[i], i+1)
            B = rec_bag(c, w, v, i+1)
            res = max(A, B)#两种方案中选最优的那个并返回
        else:
            res = rec_bag(c, w, v, i+1)#物品体积大于背包容量,直接返回
    return res

代码我没有测试过,如果有错误可以在评论区告诉我。

后面动态规划解法和另外两个问题有时间再补充。

 

Guess you like

Origin www.cnblogs.com/Alevals/p/11600947.html