動態規劃(3)——算法導論(18)

1. 寫在前面

咱們已經用動態規劃的方法解決了兩個問題,但可能仍是弄不清應該在什麼時候使用動態規劃。本篇,咱們對動態規劃方法作一個總結,重點關注適合應用動態規劃方法求解的最優化問題應該具有的兩個要素:最優子結構子問題重疊html

2. 最優子結構

用動態規劃方法求解最優化問題的第一步就是刻畫最優解的結構。如以前的兩個問題算法

若是一個問題的最優解包含其子問題的最優解,咱們就稱此問題具備最優子結構性質。app

固然,具備最優子結構性質只是判斷一個問題是否適用動態規劃方法的一個很好的線索,它也可能適用於貪心策略函數

回顧咱們以前的兩個問題。在鋼條切割問題中,咱們觀察到,長度爲n的鋼條的最優切割方案是由第一次切割後(若是最優方案須要切割)獲得的兩端鋼條的最優切割方案組成的;在矩陣乘法鏈問題中,咱們一樣看到,優化

\[ A_iA_{i+1}...A_j的最優括號化方案首先在A_k和A_{k+1}中之間進行劃分,而後對A_iA_{i+1}...A_k和A_{k+1}A_{k+2}...A_j繼續進行最優括號化 \]spa

咱們發現,在發掘最優子結構性質的過程當中,實際遵循了以下的通用模式:htm

  1. 證實問題最優解的第一個組成部分是作出了一個選擇。例如,選擇鋼條第一次切割的位置,選擇矩陣鏈的劃分位置。作出此次選擇會產生一個或多個待解的子問題。blog

  2. 對於一個給定的問題,在其可能的第一步選擇中,咱們假定已經知道哪一種選擇纔會獲得最優解。可是咱們並不關心這種選擇具體是如何獲得的,只是假定已經知道了這種選擇。遞歸

  3. 給定可得到最優解的選擇後,你肯定此次選擇會產生哪些子問題,以及如何最好的刻畫子問題空間。get

  4. 利用剪切—粘貼(cut-and-parse)技術證實:做爲構成原問題最優解的組成部分,每一個子問題的解就是它自己的最優解。利用反證法能夠證實:假設子問題的解不是其自身的最優解,那麼咱們就能夠從原問題的解中「剪切」掉這些非最優解,將最優解「粘貼」進去,從而獲得原問題一個更優的解,這與最初的解是原問題的最優解相矛盾。

一個刻畫子問題空間的好經驗是:保持子問題空間儘量簡單,但在必要時才擴展它。例如,在求解鋼條切割問題時,子問題空間中包含的問題爲:對每一個i值,長度爲i的鋼條的最優切割問題。這個子問題空間已經很通常了。

對於動態規劃問題,咱們還須要注意的兩個方面是:

  1. 原問題的最優解中,涉及多少個子問題;
  2. 在肯定最優解使用哪些子問題時,咱們須要考察多少種選擇。

例如,在鋼條切割問題中,長度爲n的鋼條的最優切割方案僅僅使用一個子問題(長度爲n-i的鋼條的最優切割問題),但咱們必須考察i的n種不一樣的取值,來肯定哪個會產生最優解。

再好比,在矩陣鏈乘法問題中,最優解使用了兩個子問題,須要考察j-i種狀況。

之因此須要注意上述兩個方面,是由於咱們能夠用來它來粗略的計算動態規劃算法的時間效率。對於鋼條切割問題,共有Θ(n)個子問題,每一個子問題最多須要考察n種選擇,所以運行時間爲O(n^2)。矩陣鏈乘法問題共有Θ(n^2)個子問題,每一個子問題最多須要考察n-1中選擇,所以運行時間爲O(n^3)。

3. 子問題重疊

適合用動態規劃問題方法求解的最優化問題應該具有的第二個性質是子問題空間必須足夠「小」,即問題的遞歸算法會反覆地求解相同的子問題,而不是一直生成新的子問題。通常來講,不一樣的子問題的總數是輸入規模的多項式函數爲好。

若是遞歸算法反覆求解相同的子問題,咱們就稱最優化問題具備摺疊子問題(overlapping)性質。

動態規劃算法一般是採用「備忘錄」來利用該性質:對每一個子問題求解一次,將解存入「備忘錄」中;當再次須要這個子問題時直接查表,這樣可保證再次求解相同問題時,只須要花費常量時間。

這裏就再也不舉例說明,可參見鋼條切割問題矩陣乘法鏈問題

相關文章
相關標籤/搜索