目錄
- 動態規劃與分治法
- 2.動態規劃求解的最優化問題應該具備的兩個要素
2.1 最優子結構
2.2 子問題重疊 - 動態規范的四個步驟
- 實例
4.1 鋼條切割
4.2 矩陣鏈乘法
4.3 最長公共子序列
4.4 最優二叉搜索樹
4.5 0-1背包問題
參見0/1背包問題——動態規劃、回溯、分支限界法對比
4.6 旅行商問題
參見旅行商(TSP)問題專題——多種方法對比
4.7 所有結點對的最短路徑問題
參見最短路徑專題
- 實例
1. 動態規劃與分治法
分治法將問題劃分為互不相交的子問題,遞歸地求解子問題,再將它們組合起來,求出原問題的解。
動態規劃應用于子問題重疊的情況,即不同的子問題具有公共的子子問題。動態規劃對每個子子問題只求解一次,將其解保存在一個表格中。
2.動態規劃求解的最優化問題應該具備的兩個要素
2.1 最優子結構
一個問題的最優解包含其子問題的最優解。(無權最長路徑就不滿足)
使用動態規劃方法時,我們用子問題的最優解來構造原問題的最優解。
1.通用模式
發掘最優子結構的通用模式:
step1.證明問題的最優解的第一個組成部分是做出一個選擇,例如,選擇鋼條第一次切割位置,選擇矩陣鏈的劃分位置等。做出選擇會產生一個或多個待解決的子問題。
step2.對于一個給定的問題,在其可能的第一步選擇中,你假定已經知道哪種才會得到最優解。
step3.給定可獲得最優解的選擇后,你確定這次選擇會產生哪些子問題,以及如何最好地刻畫子問題空間
step4.利用cut-and-paste技術證明:作為構成原問題最優解的組成部分,每個子問題的解就是它本身的最優解。
反證法:
假定子問題的解不是其自身的最優解,那么我們就可以從原問題的解中cut這些非最優解,將最優解paste進去,從而得到原問題的一個更優的解,這月最初的解是原問題的最優解的前提矛盾。
2.最優子結構的兩個方面以及運行時間的估算
對于不同問題領域,最優子結構的不同體現在兩個方面:
a.原問題的最優解設計多少個子問題
b.在確定最優解使用哪些子問題時,我們需要考察多少種選擇
可以使用子問題的總數和每個子問題需要考慮多少種選擇這兩個因素的乘積來粗略分析動態規劃的運行時間。
3.不具備最優子結構的例子
無權最短路徑:找到一條從u到v的邊數最少的路徑(具有最優子結構性質)
無權最長路徑:找到一條從u到v的邊數最多的簡單路徑(不具備)
最長路徑問題和最短路徑問題的解都用到了兩個子問題,但兩個最長簡單路徑子問題是相關的,而兩個最短路徑字問題是無關的。
根本原因是:最短路徑子問題間是不共享資源的。但是最長路徑問題求解一個子問題用到了某些資源,導致這些資源在求解其他子問題時不可用。
2.2 子問題重疊
遞歸算法反復求解相同的子問題
3. 動態規范的四個步驟
step1. 刻畫一個最優解的結構特征
step2. 遞歸地定義最優解的值
step3. 計算最優解的值,通常采用自底向上的方法
step4. 利用計算出的信息構造一個最優解
自頂向下的備忘方法優勢在于:子問題空間中某些子問題完全不必求解,因為此種方法只會求解哪些絕對必要的子問題
自底向上的方法:沒有遞歸調用的開銷,表的維護開銷也更小。
4. 實例
4.1 鋼條切割
1)最優子結構與遞歸定義最優解的值
長度為n英寸的鋼條總共有2的n-1次方種切割方案,因為每英寸的地方總可以選擇切割或者不切割。
鋼條切割問題滿足最優子結構:問題的最優解由相關子問題的最優解組合而成,而這些子問題可以獨立求解。(在所有可能的兩段切割方案中選取組合效益最大者,構成原問題的最優解)
另一種更為簡單的遞歸求解方法:將鋼條從左邊切割下長度為i的一段,只對右邊剩下的長度為n-i的一段繼續進行切割(遞歸求解),對左邊一段則不再進行切割。
證明1.為什么第二種遞歸式也成立?
證明:r(i) + r(n - i)是重復的
a. r(1) + r(n - 1) 等于 p(1) + r(n - 1)
b. r(2) + r(n - 2) 可以分解為兩個部分:
p(2) + r(n - 2)以及 p(1) + p(1) + r(n -2)
其中p(1) + p(1) + r(n - 2) 包含在a中
c.r(3) + r(n - 3)可以分解為:
p(3) + r(n - 3)
p(2) + r(1) + r(n-3) 包含在b
p(1) + r(2) + r(n-3) 包含在a
...
簡要說明如下:
對于左半邊的分割在之前的遍歷當中已經考慮到了,并不需要再考慮。
比如,如果從距離鋼條左邊2英寸處分割成兩半然后只考慮右邊的n-2英寸的鋼條的分割的話,不需要考慮將左邊2英寸的鋼條再分為兩個1英寸的情況;
因為在計算將左邊分為一個1英寸這種情況的時,另外的n-1部分其中有一種情況就是將其分為一個1寸和n-2寸的情況,這樣就考慮了之前所說的那種情況
2)自底向上計算最優解的值
3)利用計算出來的信息構造一個最優解
下面給出的是BOTTOM-UP-CUT-ROD的擴展版本,它對長隊為j的鋼條不僅計算最大收益指rj,還保存最優解對應的第一段鋼條的切割長度sj:
構造最優解:
證明2:為什么構造最優解是正確的?
證明:
長度為j的最優切割為s[j] = i,那么這個i是不用切割的,只用去切割剩下的j - i
因此一直打印s[j],然后再去切割j - s[j]
4.2 矩陣鏈乘法
完全括號化方案的數量:
當n = 1,由于只有一個矩陣,因此只有一種完全括號化方案
當n>=2,完全括號化的矩陣乘積可描述為兩個完全括號化的部分積相乘的形式:
1)最優括號化方案的結構特征
2)一個遞歸求解方案
令m[i, j]表示計算矩陣Ai..j所需的標量乘法次數的最小值
3)計算最優代價
4)構造最優解
證明:構造最優解的方法是正確的
證明:
a.當i == j時,只有一個舉證,直接打印
b.當i != j時,最外圍打印( print1 print2)
print1打印的是(s, i, k)
pirnt2打印的是(s, k + 1, j)
因為s[i, j] = k表示矩陣鏈從k處分為兩個部分
因此是完全正確的
4.3 最長公共子序列
子序列的定義:一個給定的子序列,就是將給定序列中零個或多個元素去掉之后得到的結果。
1)LCS的最優子結構
2)一個遞歸解
定義c[i, j]表示Xi和Yj的LCS的長度。
3)計算LCS的長度
4)構造LCS
正確性證明:
完全根據2)中公式進行,分為三種情況:
4.4 最優二叉搜索樹
在給定單詞出現頻率的前提下,我們應該如何組織一顆二叉搜索樹,使得所有搜索操作訪問的結點總數最少。
1)最優子結構
2)一個遞歸算法
3)計算最優解
4.5 0-1背包問題
參見0/1背包問題——動態規劃、回溯、分支限界法對比
1)問題的定義
2)最優子結構
3)遞歸算法
4)計算最優解
4.6 旅行商問題
- 一個售貨員必須訪問n個城市,恰好訪問每個城市一次,并最終回到出發城市。
售貨員從城市i到城市j的旅行費用是一個整數,旅行所需的全部費用是他旅行經過的的各邊費用之和,而售貨員希望使整個旅行費用最低。 - (等價于求圖的最短哈密爾頓回路問題)令G=(V, E)是一個帶權重的有向圖,頂點集V=(v0, v1, ..., vn-1)。從圖中任一頂點vi出發,經圖中所有其他頂點一次且只有一次,最后回到同一頂點vi的最短路徑。
4.6.1 刻畫一個最優解的結構特征(最優子結構)
- 假設s0s1s2...sn,其中s0=sn,是一條從s0出發的最短簡單回路。
那么有sisi+1...sn也是從si出發,回到起點sn的一條最短回路。(cut-and-paste證明)
4.6.2 遞歸地定義最優解的值(重疊子問題)
- 設TSP頂點編號為0,1,2,...,n-1.
假設從頂點0出發 - d(i, V')定義為從頂點i出發經過V'中各頂點有且僅有一次,最后回到頂點0的最短路徑長度
- cij定義為頂點i到頂點j的距離
一個示例:
4.6.3 計算最優解的值,通常采用自底向上的方法
- 假設頂點總數為n
則6.2中表的i范圍是0 ≤ i ≤ n-1,j的范圍是0 ≤ j ≤ 2n-1 - 1 -
一個特別的規律:k表示第k-1位上是否為1,如下圖所示
因此將一個集合轉變成了一個數與之對應,數中對應的為位1,表示該數包含在集合中,否則,該數不在集合中。
4.6.4 利用計算出的信息構造一個最優解
4.7 所有結點對的最短路徑問題
所有結點對最短路徑問題
對于每對結點u和v,找到從結點u到結點v的最短路徑。基本方法和重復平方法——Θ(n4)和Θ(n3lgn)
1)動態規劃
2)基本方法去掉一個不確定的邊,需要遍歷找到是哪個邊
3)重復平方法與基本方法的區別在于:基本方法到最終解,每次增加一條邊;重復平方法每次增加一倍。Floyd-Warshall——Θ(n3)
1)動態規劃
2)Floyd-Warshall去掉中間一個確定的點,不用遍歷求最小