python 動態規劃 鋼條切割例題 實現

2021-08-26 12:02:18 字數 2359 閱讀 8593

學習動態規劃問題時,較為經典的分析例題,分別通過遞迴,備忘錄和自下而上的方式基於python實現的練習。

首先由斐波那契數列進行練習:

# 斐波那契數列   遞迴

def fibo(n):

if n <= 0:

return 0

if n == 1:

return 1

return fibo(n-1)+fibo(n-2)

# 斐波那契數列   非遞迴

(一)自頂向下的備忘錄版本

def fibonacci(n):

sum_list = [0] * (n + 1)

def fibo(n, sum_list):

if sum_list[n] != 0:

return sum_list[n]

if n <= 2:

sum_list[n] = 1

else:

sum_list[n] = fibo(n-1, sum_list)+fibo(n-2, sum_list)

# print(sum_list)

return sum_list[n]

return fibo(n, sum_list)

通過定義sum_list列表(n+1個元素)來記錄斐波那契數列中每乙個值,

如果存在sum_list中的值,省去遞迴直接進行計算,

如果sum_list中沒有斐波那契中的值,

再利用遞迴進行計算並儲存在sum_list中。省去了重複計算。

(二)自低而上

def fibo(n):

if n <= 1:

return n

s1 = 0

s2 = 1

sum = 1

for i in range(1,n):

sum = s1+ s2

s1 = s2

s2 = sum

return sum

但是備忘錄方法還是使用到了遞迴,並產生額外的開銷。

所以,可以先運算元問題,fib(1),fib(2),fib(3)……等,

即動態規劃核心:先計算子問題再計算父問題。

現在轉至切割鋼條問題:

例題:鋼條切割

(一)

# 遞迴版本

def value_max(p, n):

if n == 0:

return 0

q = 0

for i in range(0, n):

q = max(q, p[i]+value_max(p, n-i-1))

return q

(二)

同斐波那契,多新增了乙個max的函式用來篩選,再新增乙個列表r用來記錄。

# 備忘錄版本

def cutmemo(p, n):

r = [0]* (n+1)

def value_max(p, n, r):

if n == 0:

return 0

q = 0

for i in range(0, n):

q = max(q, p[i] + value_max(p, n-i-1, r))

r[i] = q

print(r)

return q

return value_max(p, n, r)

(三)

# 自下而上的動態規劃

def cutmemo(p, n):

r = [0] * (n+1)

for i in range(1, n+1):

if n == 0:

return 0

q = 0

for j in range(1, i+1):

q = max(q, p[j-1]+r[i-j])

r[i] = q

return r

文章參考

動態規劃 鋼條切割

一家公司購買長鋼條,將其切割成短鋼條 切割本身沒有成本,長度為i的短鋼條的 為pi。那給定一段長度為n的鋼條和乙個 表pi,求鋼條的切割方案使得收益rn最大。如乙個pi如下 長度i12 3456 78910 pi15 891017 1720 2430 在距離鋼條左端i長度處,我們總是可以選擇切割或者...

動態規劃 鋼條切割

這是演算法導論動態規劃的乙個例子,自己實現了一下 給定乙個長度為n英吋的鋼條和乙個 表pi i 1,2 n 求切割鋼條方案,使得銷售收益rn最大。注意,如果長度為n的鋼條 pn足夠大,則最優解可能就不需要切割。分析 如下 include include include using namespace...

動態規劃 鋼條切割

動態規劃 dynamic programming 什麼是動態規劃,我們要如何描述它?動態規劃演算法通常基於乙個遞推公式及乙個或多個初始狀態。當前子問題的解將由上一次子問題的解推出。動態規劃和分治法相似,都是通過組合子問題的解來求解原問題。分治法將問題劃分成互不相交的子問題,遞迴求解子問題,再將他們的...