背包问题
已知有n个物品组成的集合为S,每个物品的重量是 weighti w e i g h t i 。一个背包能装重量是weight的东西。问能从S中挑选出几件物品重量之和恰好为weight。如果存在就说这个背包问题有解,如果不存在该背包问题无解。
把背包问题写成符号的形式:
bag(weight,n)
b
a
g
(
w
e
i
g
h
t
,
n
)
可以从最后一个物品来看看什么情况,当选择最后一个物品放入背包,此时问题变化为,当背包能装重量是
weight−weightn
w
e
i
g
h
t
−
w
e
i
g
h
t
n
,有n-1个物品,从这n-1个物品中挑选出若干件物品其重量之和恰好是
weight−weightn
w
e
i
g
h
t
−
w
e
i
g
h
t
n
bag(weight−weightn,n−1)
b
a
g
(
w
e
i
g
h
t
−
w
e
i
g
h
t
n
,
n
−
1
)
当不选择最后一个物品,但是如果能从n-1个物品中找到解,那么这个解也就是原问题的解。
bag(weight,n−1)
b
a
g
(
w
e
i
g
h
t
,
n
−
1
)
本来是 bag(weight,n) b a g ( w e i g h t , n ) 问题可以化解为 bag(weight,n−1)orbag(weight−weightn,n−1) b a g ( w e i g h t , n − 1 ) o r b a g ( w e i g h t − w e i g h t n , n − 1 ) 可以逐步进行递归。
def bag(weight,wlist,n):
#结束条件
if weight==0:
return True
if weight<0 or (weight>0 and n<1):
return False
#没有考虑把最后一个物品放入bag
if bag(weight,wlist,n-1):
return True
if bag(weight-wlist[n-1],wlist,n-1):
print("Item"+str(n)+":"+wlist[n-1])
return True
else:return False
函数中涉及到了两个递归函数,最终一层层的调用,每层的函数帧会形成一个类似一个二叉树的形式{如果使用栈来代替递归}。