程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 矩陣鏈乘法

矩陣鏈乘法

編輯:C++入門知識

    給定有n個要相乘的矩陣構成的序列(鏈)<A1,A2,A3,.......,An>,要計算乘積A1A2.....An。一組矩陣是加全部括號的。矩陣鏈加括號對運算的性能有很大影響。
      僅當兩個矩陣A和B相容(即A的列數等於B的行數),才可以進行相乘運算。如果A是一個p×q矩陣,B是q×r矩陣,結果C是p×r的矩陣。計算C的時間由乘法運算次數決定的,次數為p×q×r。
      矩陣鏈乘法問題可表述為:給定n個矩陣構成的一個鏈<A1,A2,A3.......,An>,其中i=1,2,3,4.....,n,矩陣Ai的維數為Pi-1 ×Pi,對乘積A1A2A3.....An,以一種最小標量乘法次數的方式進行加全部括號。
      對AiAi+1.......Aj的任何家全部括號形式都將乘積在Ak和Ak+1之間分開,即計算矩陣Ai...k和Ak+1.....Aj,然後將他們相乘得到最終的乘積Ai.......j.加全括號的代價是Ai...k和Ak+1...j的代價之和,再加上兩者相乘的代價。
      加全部括號最小代價的遞歸定義:
             m[i,j]=min{m[i,k] + m[k+1,j] + Pi-1 * Pk *Pj} ;i<j;            m[i,j]=0; i==j;
    計算最優代價時,使用輔助表m[n][n]來保存m[i][j],使用s[n][n]來記錄計算m[i][j]時取得的最優代價處的k值,即每一個表項s[i][j]都記錄了對乘積AiAi+1......Aj在Ak和Ak+1之間進行分裂取得的最優加全部括號時的k值。
    全部代碼如下:
[cpp] 
//計算矩陣鏈乘積所需的最有標量乘法次數 
void MATRIX_CHAIN_ORDER(int PArray[], int m[][PArrayLength], int s[][PArrayLength], int Length) 

    int n=Length-1;//表示有n個矩陣相乘 
    int temp=0;//臨時變量 
    for (int i=1; i<Length; i++) 
    { 
        m[i][i]=0;//先將代價初始化為0;長度為1的鏈最小代價為0 
    } 
    for (int l=2; l<=n; l++)//從第二個鏈開始分別計算長度為2、3、。。n的鏈的最小代價 
    { 
        for (int i=1; i<=n-l+1; i++) 
        { 
            int j=i+l-1; 
            m[i][j]=0x7fffffff; 
            for(int k=i; k<j; k++)//逐個檢驗K值,找到最小代價的k值 
            { 
                temp=m[i][k]+m[k+1][j]+PArray[i-1]*PArray[k]*PArray[j]; 
                if (temp<m[i][j]) 
                { 
                    m[i][j]=temp; 
                    s[i][j]=k; 
                } 
            } 
        } 
    } 

//構造一個最優解 
void PRINT_OPTIMAL_PARENS(int s[][PArrayLength], int i, int j) 

    if (i==j) 
    { 
        cout<<"A"<<i; 
    }  
    else 
    { 
        cout<<"("; 
        PRINT_OPTIMAL_PARENS(s, i, s[i][j]); 
        PRINT_OPTIMAL_PARENS(s, s[i][j]+1, j); 
        cout<<")"; 
    } 

結果:

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved