演算法導論——矩陣鏈乘法

來源:互聯網
上載者:User

【問題描述】
給定有n個連乘矩陣的維數,要求計算其採用最優計算次序時所用的乘法次數,即所要求計算的乘法次數最少。例如,給定三個連乘矩陣{A1,A2,A3}的維數分別是10*100,100*5和5*50,採用(A1A2)A3,乘法次數為10*100*5+10*5*50=7500次,而採用A1(A2A3),乘法次數為100*5*50+10*100*50=75000次乘法,顯然,最好的次序是(A1A2)A3,乘法次數為7500次。
分析:
矩陣鏈乘法問題描述:
給定由n個矩陣構成的序列[A1,A2,...,An],對乘積A1A2...An,找到最小化乘法次數的加括弧方法。
1)尋找最優子結構
此問題最難的地方在於找到最優子結構。對乘積A1A2...An的任意加括弧方法都會將序列在某個地方分成兩部分,也就是最後一次乘法計算的地方,我們將這個位置記為k,也就是說首先計算A1...Ak和Ak+1...An,然後再將這兩部分的結果相乘。
最優子結構如下:假設A1A2...An的一個最優加括弧把乘積在Ak和Ak+1間分開,則首碼子鏈A1...Ak的加括弧方式必定為A1...Ak的一個最優加括弧,尾碼子鏈同理。
一開始並不知道k的確切位置,需要遍曆所有位置以保證找到合適的k來分割乘積。
2)構造遞迴解
設m[i,j]為矩陣鏈Ai...Aj的最優解的代價,則
              ┌ 0 如果i = j
m[i,j] = │
             └ min(i≤k<j) {m[i,k] + m[k+1,j] + p[i-1] * p[k] *p[j] } 如果i<j
3)構建輔助表,解決重疊子問題
從第二步的遞迴式可以發現解的過程中會有很多重疊子問題,可以用一個nXn維的輔助表m[n][n] s[n][n]分別表示最優乘積代價及其分割位置k 。
輔助表s[n][n]可以由2種方法構造,一種是自底向上填表構建,該方法要求按照遞增的方式逐步填寫子問題的解,也就是先計算長度為2的所有矩陣鏈的解,然後計算長度3的矩陣鏈,直到長度n;另一種是自頂向下填表的備忘錄法,該方法將表的每個元素初始化為某特殊值(本問題中可以將最優乘積代價設定為一極大值),以表示待計算,在遞迴的過程中逐個填入遇到的子問題的解。

#include<iostream>using namespace std;#define N 7//p為矩陣鏈,p[0],p[1]代表第一個矩陣,p[1],p[2]代表第二個矩陣,length為p的長度//所以如果有六個矩陣,length=7,m為儲存最優結果的二維矩陣,s為儲存選擇最優結果路線的//二維矩陣void MatrixChainOrder(int *p,int (*m)[N],int (*s)[N],int length){    int n=length-1;    int l,i,j,k,q=0;    //m[i][i]只有一個矩陣,所以相乘次數為0,即m[i][i]=0;    for(i=1;i<length;i++)    {        m[i][i]=0;    }    //l表示矩陣鏈的長度    // l=2時,計算 m[i,i+1],i=1,2,...,n-1 (長度l=2的鏈的最小代價)    for(l=2;l<=n;l++)    {        for(i=1;i<=n-l+1;i++)        {            j=i+l-1; //以i為起始位置,j為長度為l的鏈的末位,            m[i][j]=0x7fffffff;            //k從i到j-1,以k為位置劃分            for(k=i;k<=j-1;k++)            {                q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];                if(q<m[i][j])                {                    m[i][j]=q;                    s[i][j]=k;                }            }        }    }    cout << m[1][N-1] << endl;}void PrintAnswer(int(*s)[N],int i,int j){    if(i==j)    {        cout<<"A"<<i;    }    else    {        cout<<"(";        PrintAnswer(s,i,s[i][j]);        PrintAnswer(s,s[i][j]+1,j);        cout<<")";    }}int main(){    int p[N]={20,35,15,5,10,20,25};    int m[N][N],s[N][N];    MatrixChainOrder(p,m,s,N);    PrintAnswer(s,1,N-1);    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.