動態規劃演算法Dynamic Programming

2021-09-01 11:05:40 字數 2079 閱讀 9167

動態規劃與分治法相似,都是通過組合子問題的解來求解原問題。不同的是,分治法將問題劃分為互不相交的子問題,遞迴的求解子問題,再將他們的解組合起來,求出原問題的解。與之相反,動態規劃應用於子問題重疊的情況,即不同的子問題具有公共的子子問題。在這種情況下,分治法會做許多不必要的工作,他會反覆求解那些公共子子問題。而動態規劃只會對子子問題求解一次,將其儲存在乙個**中,從而避免每次求解時都重新計算。現在我們來逐步的優化乙個經典的問題——最長公共子串行,從中分析動態規劃的思想方法。

最長公共子串行問題(longest-common-subsequence problem)給定兩個序列x=和y=,求x和y的長度最長的公共子串行。

我們把問題分割成兩個部分:遍歷和判斷。首先遍歷x的所有的子串行,然後依次進行判斷是否為y的子串行,並比較得出其中最長的乙個。

對於判斷,可以從左向右掃瞄一遍即可實現,複雜度為o(n):

/**

* 判斷sub是否為a的子串行

* @param a

* @param sub

* @return

*/private static boolean issubsequence(char a,char sub)else if (k==chars.length) 0 &if\ i=0\ or j=0 \\ c[i-1,j-1]+1 & if\ i,j/>0\ and\ xi=yj\\ max(c[i,j-1],c[i-1,j]) & if\ i,j>0\ and\ xi!=yj \end\right." class="mathcode" src="">

有了這個遞迴公式,我們就可以寫出乙個指數時間的演算法來進行遞迴計算了:

/*** 直接根據遞迴公式進行求解最長公共子串行

* @return

*/private static int dpforlcs(char a,char b,int i,int j,stackstack,boolean aflag)else

return dpforlcs(a, b, i-1, j-1,stack,aflag)+1;

}else

}}

可以看出上面直接根據遞迴公式進行求解的方法會有很多的重複計算,比如為了求x和y的乙個lcs,我們可能需要求x和yn-1的乙個lcs以及xm-1和y的乙個lcs,這幾個問題都會包含xm-1和yn-1的lcs這個子問題,對於這種情況,我們將它描述為具有重疊子問題性質。解決的思路是借助快取的思想,將已經計算出的子問題儲存在乙個**裡以避免重複進行計算。一般的,可以有如下的遞迴和迭代兩種實現方式。

此方法依然按照自然的遞迴形式編寫函式,但函式中會儲存每個字問題的解(通常儲存在乙個陣列或者雜湊表中)。當需要乙個子問題的解時,函式會首先檢查是否儲存過此解。如果是,直接返回儲存的值,從而節省了計算時間。

/**

* 自頂向下法(遞迴形式的動態規劃)

*/private static int dpforlcsdown(char a,char b,int i,int j,int length)elseelse

}}

把子問題按照規模進行排序,按照由小至大的順序進行求解。當解決某個子問題時,它所依賴的更小的子問題都已經求解完畢,結果已經儲存,每個子問題都只需求解一次。

/*** 自底向上法(迭代形式的動態規劃)

*/private static int dpforlcsup(char a,char b){

int length=new int[a.length][b.length];

for(int i=0;i上述兩種方法具有相同的漸進執行時間,但是由於沒有頻繁的遞迴函式呼叫的開銷,自底向上方法的時間複雜度函式通常具有更小的係數。

從上面的討論過程中,我麼可以看到適用動態規劃演算法求解的最優化問題應該具有兩個要素:最優子結構性質和子問題重疊。首先,最優子結構性質可是使我們避免暴力遍歷所有的子串行;其次,子問題重疊性質可以使我們借助快取思想,避免對相同的子問題進行重複求解,從而達到比傳統分治法更優的效能。最後,我們提煉出設計乙個動態規劃演算法的步驟:

[1]thomas h.cormen charles e.leiserson.introduction to algorithms(third edition)[m].china machine press,2013

動態規劃演算法

一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...

動態規劃演算法

動態規劃 通過把原問題分解為相對簡單的子問題來求解複雜問題。動態規劃常常適用於有重疊子問題和最優子結構性質的問題。演算法總體思想 演算法的基本步驟 演算法的基本要素 最優子結構 重疊子問題 備忘錄方法 問題描述 子串行 公共子串行 最長公共子串行 lcs 問題 問題分析 動態規劃求解lcs問題 最長...

動態規劃演算法

動態規劃演算法的思路 動態規劃法即 dynamic programming method dp 是系統分析中的種常用方法。動態規劃法是20世紀50年代由貝爾曼 r.bellman 等人提出的,用來解決多階段決策過程問題的一種最優化方法。多階段決策過程是指把研究問題分成若干個相互聯絡的階段,由每個階段...