#include<iostream> using namespace std; /************************************* i,i,i,i,i,i,i,i,i,i,i,i,i,i j,j,j,j,j,j,j,j,j,j,j,j r=2 1,2,3.....................n-1 2 , 3................n r=3 1,2,3................n-2 3 , 4..............n r=4 1,2,3...........n-3 4 , 5............n . . r=n-1 1,2 n-1,n r=n 1 n k>=i+1 && k<j **************************************/ void MatrixChain(int *p,int n,int** m,int** s){ for(int i=1;i<=n;i++) m[i][i]=0; for(int r=2;r<=n;r++){ for(int i=1;i<=n-r+1;i++){ int j=i+r-1; m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; //在Ai和Ai+1之间断开 s[i][j]=i; for(int k=i+1;k<j;k++){ int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; //在Ak和Ak+1之间断开 if(t<m[i][j]){ m[i][j]=t; s[i][j]=k; } } } } } void Traceback(int i,int j,int** s){ if(i==j) return; Traceback(i,s[i][j],s); Traceback(s[i][j]+1,j,s); cout<<"Multiply A"<<i<<","<<s[i][j]; cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl; } /******************* 例如:设要计算矩阵连乘积A1A2A3A4A5A6,其中各矩阵的维数分别为: A1(30*35) A2(35*15) A3(15*5) A4(5*10) A5(10*20) A6(20*25) 最优计算次序(A1(A2A3))((A4A5)A6) ********************/ int main(void ){ int n=6;//矩阵的个数 int *p=new int[n+1]; //p[0]:第一个矩阵的行数 //p[1]:第一个矩阵的列数,第二个矩阵的行数 //p[2]:第二个矩阵的列数,第三个矩阵的行数 p[0]=30; p[1]=35; p[2]=15; p[3]=5; p[4]=10; p[5]=20; p[6]=25; int **m,**s; m=new int*[n+1]; for( int i=0;i<n+1;i++) m[i]=new int[n+1]; s=new int*[n+1]; for(int i=0;i<n+1;i++) s[i]=new int[n+1]; MatrixChain(p,n,m,s); Traceback(1,n,s); for(int i=0;i<n;i++) { delete []m[i]; m[i]=NULL; delete []s[i]; s[i]=NULL; } delete []m; m=NULL; delete []s; s = NULL; delete []p; p = NULL; return 0; }
矩阵连乘问题目的是减少计算量,为了减少乘法的次数,计算次序非常重要,m[i][j]为Ai..Aj连乘的最优值,Ai..Aj连乘在A(s[i][j])处断开先计算Ai..A(s[i][j]),再计算
A(s[i][j]+1)..Aj,算法采用王晓东所著《计算机算法设计与分析》中的算法,具体细节参见此书。