0-1背包问题(Knapsack Problem)-动态规划方法(C语言递归和迭代)

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(n1,

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值