3人对饮

导航

 
#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,算法采用王晓东所著《计算机算法设计与分析》中的算法,具体细节参见此书。

posted on 2012-07-12 18:03  3人对饮  阅读(1567)  评论(0编辑  收藏  举报