天天看點

動态規劃

一、基本概念

    動态規劃過程是:每次決策依賴于目前狀态,又随即引起狀态的轉移。一個決策序列就是在變化的狀态中産生出來的,是以,這種多階段最優化決策解決問題的過程就稱為動态規劃。

二、基本思想與政策

    基本思想與分治法類似,也是将待求解的問題分解為若幹個子問題(階段),按順序求解子階段,前一子問題的解,為後一子問題的求解提供了有用的資訊。在求解任一子問題時,列出各種可能的局部解,通過決策保留那些有可能達到最優的局部解,丢棄其他局部解。依次解決各子問題,最後一個子問題就是初始問題的解。

    由于動态規劃解決的問題多數有重疊子問題這個特點,為減少重複計算,對每一個子問題隻解一次,将其不同階段的不同狀态儲存在一個二維數組中。

    與分治法最大的差别是:适合于用動态規劃法求解的問題,經分解後得到的子問題往往不是互相獨立的(即下一個子階段的求解是建立在上一個子階段的解的基礎上,進行進一步的求解)。

三、适用的情況

能采用動态規劃求解的問題的一般要具有3個性質:

    (1) 最優化原理:如果問題的最優解所包含的子問題的解也是最優的,就稱該問題具有最優子結構,即滿足最優化原理。

    (2) 無後效性:即某階段狀态一旦确定,就不受這個狀态以後決策的影響。也就是說,某狀态以後的過程不會影響以前的狀态,隻與目前狀态有關。

   (3)有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被多次使用到。(該性質并不是動态規劃适用的必要條件,但是如果沒有這條性質,動态規劃算法同其他算法相比就不具備優勢)

四、求解的基本步驟

     動态規劃所處理的問題是一個多階段決策問題,一般由初始狀态開始,通過對中間階段決策的選擇,達到結束狀态。這些決策形成了一個決策序列,同時确定了完成整個過程的一條活動路線(通常是求最優的活動路線)。如圖所示。動态規劃的設計都有着一定的模式,一般要經曆以下幾個步驟。

    初始狀态→│決策1│→│決策2│→…→│決策n│→結束狀态

                      圖1 動态規劃決策過程示意圖

    (1)劃分階段:按照問題的時間或空間特征,把問題分為若幹個階段。在劃分階段時,注意劃分後的階段一定要是有序的或者是可排序的,否則問題就無法求解。

    (2)确定狀态和狀态變量:将問題發展到各個階段時所處于的各種客觀情況用不同的狀态表示出來。當然,狀态的選擇要滿足無後效性。

    (3)确定決策并寫出狀态轉移方程:因為決策和狀态轉移有着天然的聯系,狀态轉移就是根據上一階段的狀态和決策來導出本階段的狀态。是以如果确定了決策,狀态轉移方程也就可寫出。但事實上常常是反過來做,根據相鄰兩個階段的狀态之間的關系來确定決策方法和狀态轉移方程。

    (4)尋找邊界條件:給出的狀态轉移方程是一個遞推式,需要一個遞推的終止條件或邊界條件。

    一般,隻要解決問題的階段、狀态和狀态轉移決策确定了,就可以寫出狀态轉移方程(包括邊界條件)。

實際應用中可以按以下幾個簡化的步驟進行設計:

    (1)分析最優解的性質,并刻畫其結構特征。

    (2)遞歸的定義最優解。

    (3)以自底向上或自頂向下的記憶化方式(備忘錄法)計算出最優值

    (4)根據計算最優值時得到的資訊,構造問題的最優解

五、算法實作的說明

    動态規劃的主要難點在于理論上的設計,也就是上面4個步驟的确定,一旦設計完成,實作部分就會非常簡單。

     使用動态規劃求解問題,最重要的就是确定動态規劃三要素:

    (1)問題的階段 (2)每個階段的狀态

    (3)從前一個階段轉化到後一個階段之間的遞推關系。

     遞推關系必須是從次小的問題開始到較大的問題之間的轉化,從這個角度來說,動态規劃往往可以用遞歸程式來實作,不過因為遞推可以充分利用前面儲存的子問題的解來減少重複計算,是以對于大規模問題來說,有遞歸不可比拟的優勢,這也是動态規劃算法的核心之處。

    确定了動态規劃的這三要素,整個求解過程就可以用一個最優決策表來描述,最優決策表是一個二維表,其中行表示決策的階段,清單示問題狀态,表格需要填寫的資料一般對應此問題的在某個階段某個狀态下的最優值(如最短路徑,最長公共子序列,最大價值等),填表的過程就是根據遞推關系,從1行1列開始,以行或者列優先的順序,依次填寫表格,最後根據整個表格的資料通過簡單的取舍或者運算求得問題的最優解。

          f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}

動态規劃
動态規劃

代碼

1 for(j=1; j<=m; j=j+1) // 第一個階段

2   xn[j] = 初始值;

3

4  for(i=n-1; i>=1; i=i-1)// 其他n-1個階段

5   for(j=1; j>=f(i); j=j+1)//f(i)與i有關的表達式

6 xi[j]=j=max(或min){g(xi-1[j1:j2]), ......, g(xi-1[jk:jk+1])};

8

9 t = g(x1[j1:j2]); // 由子問題的最優解求解整個問題的最優解的方案

10

11 print(x1[j1]);

12

13 for(i=2; i<=n-1; i=i+1)

15 {

17 t = t-xi-1[ji];

18

19 for(j=1; j>=f(i); j=j+1)

21 if(t=xi[ji])

23 break;

25 }

動态規劃

A thousand journey is started by taking the first step.