動態規划求解矩陣連乘問題


題目

  給定n個矩陣{A1,A2,…,An}(其中,矩陣Ai的維數為pi-1*pi,i=1,2,3,…,n),如何確定計算矩陣的連乘積A1,A2,…,An的計算次序(完全加括號方式),使得此次序計算矩陣連乘積需要的數乘次數最少。

步驟

 

  • 分析最優解的結構 

  將矩陣連乘積AiAi+1…Aj簡記為A[i:j],則原式記為A[1:n]。

  將矩陣鏈在Ak和Ak+1之間斷開,1≤k<n,則AiAi+1…Aj=(A1...Ak)(A1...Ak)。我們只要計算A[1:k]以及A[k+1:n],再將二者相乘則可得出結果。

  我們只需要保證A[1:k]以及A[k+1:n]的計算次序也是最優的,那么A[1:n]的計算次序也就是最優的了(最優子結構的性質)。

  • 建立遞歸關系

  計待求問題最優值的乘積次數為m[i][j]。

  i = j 時,A[i: j]=Ai,m[i][j]=0,i=1,2,…,n

  i < j 時,根據矩陣數乘的性質得:m[ i ][ j ] = m[ i ][ k ] + m[ k+1][ j ] + pi-1 pk pj

  又因為k的位置未定,而k的可能取值范圍為i,i+1,…,j-1,因此k是這j-1個位置中使得m[ i ][ j ]的值達到最小的位置。可以得到遞推關系

   i < j 時 ,m[ i ][ j ] = min { m[ i ][ k ] + m[ k+1][ j ] + pi-1 pk p}  , i ≤ k < j

  將對應m[ i ][ j ]的斷開位置k記為s[ i ][ j ],則之后可遞歸地由s[ i ][ j ]構造出相應的最優解

  • 計算最優值

  依據其遞歸式,自底向上的計算。

  下列算法中,輸入參數{p0,p1,…,pn}。

 1 void MatrixChain(int *p, int n, int**m, int **s){
 2     for{int i=1;i<=n;i++) m[i][j]=0;
 3     for(int r=2;r<=n;r++){
 4         for(int r =2;r<=n;r++){
 5             int j=i+r-1;
 6             m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];
 7             s[i][j] = i;
 8             for(int k =i+1;k<j;k++){
 9                 int t = m[i][k]+m[k+1][j] +  p[i-1]*p[i]*p[j];
10                 if(t< m[i][j]){ m[i][j] =t ; s[i][j] =k;}
11             }
12         }
13     }
14 }        
View Code

  該算法先計算出m[ i ][ i ],然后依次計算m[ i ][ i+1 ],m[ i ][ i+2 ],…,m[ i ][ j ]。在計算m[ i ][ j ]時,只需要用到之前計算過的m[ i ][ k ]和m[ k+1 ][ j ]。

  算法的主要計算量取決於r,i,k的三重循環,因此時間復雜度為O(n3),空間復雜度為O(n2)。

  • 構造最優解

  s[ i ][ j ]表示A[i: j]的最佳斷開位置為Ak和Ak+1

  因此A[1: n]的最佳加括號方式為(A[1: s[ 1 ][ n ]) (A[s[ 1 ][ n ]+1: n])  //s[ i ][ j ]存的是相應的k

    A[1: s[ 1 ][ n ] ] 的最佳加括號方式為(A[ 1 : s[ 1 ][ s[ 1 ][ n ] ] ]) (A[ s[ 1 ][ s[ 1 ][ n ] ] +1 : s[ 1 ][ n ])

  遞推。

1 void Traceback(int i, int j, int **s){
2     if(i==j) return;
3     Traceback(i, s[ i ][ j ],s);
4     Traceback(s[ i ][ j ]+1 ,j ,s);
5 
6     cout<<"Multiply A" <<i<<", "<<s[ i ][ j ];
7     cout<<" and A "<<(s[ i ][ j ]+1)<<", "<<j<<endl;
8 }
View Code

 要輸出A[1: n]的最優計算次序只需要調用Traceback(1 , n, s)即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM