0-1背包问题(Knapsack Problem)-动态规划方法(递归和迭代)
前言
背包0-1问题属于典型的求最大/最小子集问题范畴,它不像rod-cutting或matrix-chain-multiplication等问题,求解过程是按照单位等增或单位递减,0-1背包问题属于在集合范围内的某一个值,而且这些值大概率不是连续值。
问题描述
假定有N件物品,每件物品具有特定的价值value[i]和重量weight[i](1<=i<=N);现给定一个背包,此背包有总重量的限制W,求解这个包装载的物品具有最大价值和。
为什么把此问题称作0-1问题呢? 因为每件物品都有两种状态,如果没有选择,可以称作为状态0,如果选择,那么可以标记为状态1.
用具体的示例进行说明,为了阐述方便,我们规定物品有3件,背包最大承重W<=50kg, 表格勾画出问题。
| Item # No. | Value | Weight |
|---|---|---|
| 1 | 60 | 10 |
| 2 | 100 | 20 |
| 3 | 120 | 30 |
如果我们用穷举法,可以得到8类不同的组合,对于每个不同组合,可以计算其总价值和总重量,最后选择满足总重量要求的最大价值。

其中灰色代表左边的物件未放入背包,绿色代表物件已经背包,需要考虑其重量和价值。我们以C3选择为例说明,C3选择了物件1和物件2放入背包,那么我们就可以求出背包内所放置物品的价值总和 与 重量总和**(160,30)**。
s u m _ v a l u e = ∑ ( 60 + 100 ) = 160 sum\_value=∑(60+100)=160 sum_value=∑(60+100)=160
s u m _ w e i g h t = ∑ ( 10 + 20 ) = 30 sum\_weight=∑(10+20)=30 sum_weight=∑(10+20)=30
通过观察,可以发现C7包含的价值最大,为280;但同时如果考虑背包所能最大的承重 W<=50,那么显然C7不符合求解要求。再继续观察,我们发现 C6组合**(220,50)**既满足背包最大承重要求,也满足价值最大的要求,那么C6就是我们最终的选择,也即选择物件2和物件3放入背包,可以获得最大的价值。
针对三件物品,我们可以采用穷举法罗列所有可能的选项,如果物品件数较多,假设有10件物品,就需要罗列1024次才可能求出最终的解;假定有N件物品,如果采用穷举法,我们需要进行2^N 罗列才能求出解,显然这样效率很低,在N较大时候,程序运行效率很低,甚至无法求解。
按照《算法导论》的模板,仍然采用CRCC模式对此问题进行分析。
a) 表征最优解的结构(Characterize the structure of optimal solution)
要计算背包所能装载的最大价值,同时满足背包的承重要求。如果我们走一个极端,如果背包可以无限承重,那么此问题就转换为所有物品价值简单求和的问题,因为物品的价值总为正,物品越多,那么其放入背包后的价值就越大,在此极端情况下,我们不需要用到任何优化,运用动态规划意义不大。
所以我们最优解的结构一定包含两个参数,参数之一为物件的数量n(1<=n<=N),另外一个参为背包的最大承重W,作为约束条件物件的重量总和必须≤W.
如果采用朴素的函数语言,我们可以将表征最优解的结构抽象为函数结构:
f ( n , w ) = m a x { f ( n − 1 , w ) , f ( n − 1 , w − w e i g h t [ n ] ) + v a l u e [ n ] } o r f ( n − 1 , w ) f(n,w)=max\{f(n-1,w),f(n-1,w-weight[n])+value[n]\} or f(n-1,w) f(n,w)=max{
f(n−1,
动态规划解析:0-1背包问题的递归与迭代解法

最低0.47元/天 解锁文章
21万+

被折叠的 条评论
为什么被折叠?



