動態規劃(dynamic programming)是一種在數學、電腦科學和經濟學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。 動態規劃常常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。 動態規劃背後的基本思想非常簡單。大致上,若要解乙個給定問題,我們需要解其不同部分(即子問題),再合併子問題的解以得出原問題的解。 通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,從而減少計算量: 一旦某個給定子問題的解已經算出,則將其記憶化儲存,以便下次需要同乙個子問題解之時直接查表。 這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用。 關於動態規劃最經典的問題當屬揹包問題。
最優子結構性質。如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題具有最優子結構性質(即滿足最優化原理)。最優子結構性質為動態規劃演算法解決問題提供了重要線索。
子問題重疊性質。子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產生的子問題並不總是新問題,有些子問題會被重複計算多次。動態規劃演算法正是利用了這種子問題的重疊性質,對每乙個子問題只計算一次,然後將其計算結果儲存在乙個**中,當再次需要計算已經計算過的子問題時,只是在**中簡單地檢視一下結果,從而獲得較高的效率。
無後效性:即某階段狀態一旦確定,就不受這個狀態以後決策的影響。也就是說,某狀態以後的過程不會影響以前的狀態,只與當前狀態有關。
劃分:按照問題的特徵,把問題分為若干階段。注意:劃分後的階段一定是有序的或者可排序的
確定狀態和狀態變數:將問題發展到各個階段時所處的各種不同的客觀情況表現出來。狀態的選擇要滿足無後續性
邊界條件:狀態轉移方程是乙個遞推式,因此需要找到遞推終止的條件
即:
【初始狀態】→【決策1】→【決策2】→…→【決策n】→【結束狀態】
注意: 問題階段
每個階段的狀態
相鄰兩個階段之間的遞迴關係
問題描述:假設我們有n種型別的物品,分別編號為1, 2...n。其中編號為i的物品價值為vi,它的重量為wi。為了簡化問題,假定價值和重量都是整數值。現在,假設我們有乙個揹包,它能夠承載的重量是cap。現在,我們希望往包裡裝這些物品,使得包裡裝的物品價值最大化,那麼我們該如何來選擇裝的東西呢?注意:每種物品只有一件,可以選擇放或者不放。初始化資料為:n=5,w=,v=,cap=10
解法如下:
描述最優解的結構
設子問題:f[i][v]表示允許前i件物品放入容量為v的揹包時可以獲得的最大價值。注:這裡的i從0到5,v從0到10
為了能夠得到已經計算過的,更小規模的子問題,我們可以根據當前限重來只考慮第i件物品放或者不放,那麼就可以轉化為涉及前i-1件物品的問題,
#n:物品件數;c:最大承重為c的揹包;w:各個物品的重量;v:各個物品的價值
#第一步建立最大價值矩陣(橫座標表示[0,c]整數揹包承重):(n+1)*(c+1)
#技巧:python 生成二維陣列(陣列)通常先生成列再生成行
def bag(n,c,w,p):
res=[[-1 for j in range(c+1)]for i in range(n+1)]
for j in range(c+1):
#第0行全部賦值為0,物品編號從1開始.為了下面賦值方便
res[0][j]=0
for i in range(1:n+1):
for j in range(1:c+1):
res[i][j]=res[i-1][j]
#生成了n*c有效矩陣,以下公式w[i-1],p[i-1]代表從第乙個元素w[0],p[0]開始取。
if(j>=w[i-1]) and res[i-1][j-w[i-1]]+p[i-1]>res[i][j]:
res[i][j]=res[i-1][j-w[i-1]]+p[i-1]
return res
#以下**功能:標記出有放入揹包的物品
#反過來標記,在相同價值情況下,後一件物品比前一件物品的最大價值大,則表示物品i#有被加入到揹包,x陣列設定為true。設初始為j=c。
def show(n,c,w,res):
print('最大價值為:',res[n][c])
x=[false for i in range(n)]
j=c
for i in range(1,n+1):
if res[i][j]>res[i-1][j]:
x[i-1]=true
j-=w[i-1]
print '選擇的物品為:'
for i in range(n):
if x[i]:
print '第',i,'個,'
print''
if __name__=='__main__':
n=5
c=10
w=[2,2,6,5,4]
p=[6,3,5,4,6]
res=bag(n,c,w,p)
show(n,c,w,res)
這個解釋更清晰明了
動態規劃演算法
一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...
動態規劃演算法
動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...
動態規劃演算法
動態規劃演算法的思路 動態規劃法即 dynamic programming method dp 是系統分析中的種常用方法。動態規劃法是20世紀50年代由貝爾曼 r.bellman 等人提出的,用來解決多階段決策過程問題的一種最優化方法。多階段決策過程是指把研究問題分成若干個相互聯絡的階段,由每個階段...