整體思路:
當沒有物品時候返回0【遞迴終點】。
當第i個物品體積超過揹包容量時,在前i-1個物品中計算最大價值【遞迴終點】,
當第i個物品體積不超過揹包容量時,偷的結果
不偷的結果
用【遞迴】實現揹包問題:
後期要優化遞迴中重複計算問題。#coding=utf-8
class kapsnack(object):
def __init__(self):
self.weight = [0, 2, 2, 6, 5, 4]
self.values = [0, 6, 3, 5, 4, 6]
def comput(self, n=5, w=10):
if n < 0:
return 0
if self.weight[n] > w:
return self.comput(n-1, w)
else:
result1 = self.comput(n-1, w-self.weight[n]) + self.values[n]
result2 = self.comput(n-1, w)
return max(result1, result2)
n = 5
w = 10
result = kapsnack().comput(n, w)
print('揹包容量是{}的情況下,能偷到的最大的價值是{}'.format(w,result))
#揹包容量是10的情況下,最大的價值是15
python標準的直譯器沒有針對尾遞迴做優化,任何遞迴函式都存在棧溢位的問題。
上面演算法中無論第五件物品偷不偷,result1和result2都會計算一遍第四件物品的偷不偷問題,重複計算。
【字典優化版】的遞迴揹包問題:
#coding=utf-8
import timeit
class kapsnack(object):
def __init__(self):
self.weight = [0, 2, 2, 6, 5, 4]
self.values = [0, 6, 3, 5, 4, 6]
self.temp_dic = {}
def comput(self, n, w):
#若字典裡沒有計算值
if self.temp_dic.get(n, "noresult") == "noresult":
print("字典沒有結果需要計算,n是%d"%n)
#就計算
if n < 0 or w <= 0:
return 0
if self.weight[n] > w:
return self.comput(n-1, w)
else:
result1 = self.comput(n-1, w-self.weight[n]) + self.values[n]
result2 = self.comput(n-1, w)
max_result = max(result1, result2)
#計算結果扔到字典裡
self.temp_dic[n] = max_result
return max_result
#字典有值直接返回
else:
print("有結果,n是%d"%n)
return self.temp_dic[n]
n = 5
w = 10
result = kapsnack().comput(n, w)
print('揹包容量是{}的情況下,能偷到的最大的價值是{}'.format(w,result))
print(timeit.timeit("kapsnack().comput(5, 10)", setup="from __main__ import kapsnack", number=100))
"""...
字典沒有結果需要計算,n是5
字典沒有結果需要計算,n是4
字典沒有結果需要計算,n是3
字典沒有結果需要計算,n是2
字典沒有結果需要計算,n是1
字典沒有結果需要計算,n是0
字典沒有結果需要計算,n是-1
字典沒有結果需要計算,n是-1
字典沒有結果需要計算,n是3
字典沒有結果需要計算,n是2
字典沒有結果需要計算,n是1
有結果,n是0
字典沒有結果需要計算,n是2
字典沒有結果需要計算,n是1
有結果,n是0
有結果,n是0
有結果,n是1
有結果,n是4
揹包容量是10的情況下,能偷到的最大的價值是15
0.01601231499807909
"""
遞迴 揹包問題
揹包問題有許多種形式,最簡單的揹包問題形式 現在有一堆石頭,比如重量為2,6,8,10 乙個揹包中可以裝指定的重量 比如14 的石頭,請問揹包中可以放入的石頭的組合。中假設石頭是個源陣列,揹包是目標陣列。演算法中使用分治的想法將此問題遞迴為兩個小範圍的問題。針對第n個石頭,揹包問題可以分解為兩種組合...
01揹包問題 遞迴 動態規劃求解
使用記憶化搜尋 存在重疊子問題 對於index,c這一資料對可能求解多次 int memo 用 0.index 的物品,填充容積為c的揹包的最大價值 param w 物體的重量 param v 物體的價值 param index 當前考慮的物體的index序列號 param c 當前所剩容量 ret...
動態規劃揹包問題 01揹包
問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...