背包问题解析(二)-递归算法

一、题目:
有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
 
二、递归方法:
首先对于每个物品,我们的选择只有两个:放或者不放。我们将所有的可能都穷举出来,就可以得到下面这个树状图(只画了前四个结点):
 
所以对于每一个子问题,由于前面的子问题已被解决,因此我们都只需要做两个选择:放,还是不放。
假设我们已经知道了前i−1个物品放入背包的最优方案F(i−1,v i−1 ),那么对于第i个物品要放入背包就有三种情况:
1、若物品的体积c i  大于背包剩余的容量v i−1  ,那么只能丢弃这个物品:
F(i,vi)=F(i−1,vi−1)
2、否则就有两种选择:
(1)、不放第i个物品:
F(i,vi)=F(i−1,vi−1)
(2)、放第i个物品:
F(i,vi)=wi+F(i−1,vi−1−ci)
要从这两个方案中选择总价值最大的,所以:
 
三、python代码实现如下:
def rec_bag(c, w, v, i=0):
'''
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
 
a=rec_bag([2,3,4,5],[3,4,5,6],8,0)
print(a)
 
 
四、算法分析:
递归方法最大的缺点就在于有较多重复的计算,通过上面的树状图可以知道,递归会遍历这棵树的所有结点,所以它的时间复杂度为:O(2 n )
O(2n),指数阶的时间复杂度对于计算机来说简直就是灾难!
有没有什么办法减少这些重复的计算呢?这就是接下来要说的动态规划,它可以通过存储已经计算出来的结果来减少重叠子问题。
 
 

你可能感兴趣的:(背包问题解析(二)-递归算法)