揹包問題,遞迴方法的動態優化

2021-09-18 02:33:25 字數 2495 閱讀 9737

整體思路:

當沒有物品時候返回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 ...