矩陣連乘-動態規劃-(只是感覺描述的清晰易懂,並不是什麼新算法)

矩陣連乘-動態規劃-詳解

DEC 19TH2015 11:04 AM

動態規劃法

  • 以矩陣鏈ABCD爲例
  • 按照矩陣鏈長度遞增計算最優值
  • 矩陣鏈長度爲1時,分別計算出矩陣鏈A、B、C、D的最優值
  • 矩陣鏈長度爲2時,分別計算出矩陣鏈AB、BC、CD的最優值
  • 矩陣鏈長度爲3時,分別計算出矩陣鏈ABC、BCD的最優值
  • 矩陣鏈長度爲4時,計算出矩陣鏈ABCD的最優值

給定n個矩陣{A1,A2,…,An},其中Ai與Ai+1是可乘的,i=1,2…,n-1。如何確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。

解答:我們按照動態規劃的幾個步驟來分析:

(1)找出最優解的性質,刻畫其特徵結構

對於矩陣連乘問題,最優解就是找到一種計算順序,使得計算次數最少。

令m[i][j]表示第i個矩陣至第j個矩陣這段的最優解。

將矩陣連乘積 簡記爲A[i:j] ,這裏i<=j.假設這個最優解在第k處斷開,i<=k<j,則A[i:j]是最優的,那麼A[i,k]和A[k+1:j]也是相應矩陣連乘的最優解。可以用反證法證明之。 這就是最優子結構,也是用動態規劃法解題的重要特徵之一。

(2)建立遞歸關係

設計算A[i:j],1≤i≤j≤n,所需要的最少數乘次數m[i,j],則原問題的最優值爲m[1,n] 。

當i=j時,A[i,j]=Ai, m[i,j]=0;(表示只有一個矩陣,如A1,沒有和其他矩陣相乘,故乘的次數爲0)

當i<j時,m[i,j]=min{m[i,k]+m[k+1,j] +pi-1*pk*pj} ,其中 i<=k<j

(相當於對i~j這段,把它分成2段,看哪種分法乘的次數最少,如A1,A2,A3,A4,則有3種分法:{A1}{A2A3A4 }、{A1A2}{A3A4 }、{A1A2A3}{A4 },其中{}表示其內部是最優解,如{A1A2A3}表示是A1A2A3的最優解),

也即:

img

(3)計算最優值

對於1≤i≤j≤n不同的有序對(i,j) 對於不同的子問題,因此不同子問題的個數最多隻有o(n*n).但是若採用遞歸求解的話,許多子問題將被重複求解,所以子問題被重複求解,這也是適合用動態規劃法解題的主要特徵之一。

用動態規劃算法解此問題,可依據其遞歸式以自底向上的方式進行計算。在計算過程中,保存已解決的子問題答案。每個子問題只計算一次,而在後面需要時只要簡單查一下,從而避免大量的重複計算,最終得到多項式時間的算法。

下面給出動態規劃求解最優值的代碼:

void MatrixChain(int *p,int n,int **m,int **s)

{    //m是最優值,s是最優值的斷開點的索引,n爲題目所給的矩陣的個數(下面例子中)

//矩陣段長度爲1,則m[][]中對角線的值爲0,表示只有一個矩陣,沒有相乘的.

for(int i = 1;i<=n;i++) m[i][i] = 0;           //本題中n=6             

for(int r = 2;r<=n;r++){//對角線循環,r表示矩陣的長度(2,3…逐漸變長)  

   for(int i = 1;i<=n-r+1;i++){  //行循環

//從第i個矩陣Ai開始,長度爲r,則矩陣段爲(Ai~Aj)

int j = r+i-1;//列的控制,當前矩陣段(Ai~Aj)的起始爲Ai,尾爲Aj

//求(Ai~Aj)中最小的,其實k應該從i開始,但先記錄第一個值,k從i+1開始,這樣也可以。

//例如對(A2~A4),則i=2,j=4,下面一行的m[2][4]=m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)

     m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];

     s[i][j] = i;//記錄斷開點的索引

//循環求出(Ai~Aj)中的最小數乘次數

     for(int k = i+1 ; k<j;k++){

//將矩陣段(Ai~Aj)分成左右2部分(左m[i][k],右m[k+1][j]), //再加上左右2部分最後相乘的次數(p[i-1] *p[k]*p[j])

       int t = m[i][k] + m[k+1][j] + p[i-1] *p[k]*p[j];                  

       if(t<m[i][j])

       {  m[i][j] = t;  
          s[i][j] = k;  //保存最小的,即最優的結果

}//if

     }//k

    }//i

}//r

}//MatrixChain

上面代碼中後面的k也相當於是從i到j-1遞增的,只是單獨把第一個(k=i)提了出來.

對於 p={30 35 155 10 20 25}:

img

計算順序爲:

img

對上例,共6個矩陣(A1~A6),n=6,當r=3時,r循環裏面的是3個矩陣的最優解,i從1->4,即求的是

(A1A2A3),(A2A3A4),(A3A4A5),(A4A5A6)這4個矩陣段(長度爲3)的最優解.當i=2時(A2A3A4)的最優解爲{A2(A3A4) ,(A2A3)A4}的較小值。

  • 矩陣連乘計算次序問題的最優解包含着其子問題的最優解。這種性質稱爲最優子結構性質。

  • 在分析問題的最優子結構性質時,所用的方法具有普遍性:首先假設由問題的最優解導出的子問題的解不是最優的,然後再設法說明在這個假設下可構造出比原問題最優解更好的解,從而導致矛盾。

  • 利用問題的最優子結構性質,以自底向上的方式遞歸地從子問題的最優解逐步構造出整個問題的最優解。最優子結構是問題能用動態規劃算法求解的前提。

  • 遞歸算法求解問題時,每次產生的子問題並不總是新問題,有些子問題被反覆計算多次。這種性質稱爲子問題的重疊性質。

  • 動態規劃算法,對每一個子問題只解一次,而後將其解保存在一個表格中,當再次需要解此子問題時,只是簡單地用常數時間查看一下結果。

  • 通常不同的子問題個數隨問題的大小呈多項式增長。因此用動態規劃算法只需要多項式時間,從而獲得較高的解題效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章