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
代码我没有测试过,如果有错误可以在评论区告诉我。
后面动态规划解法和另外两个问题有时间再补充。