当前位置:编程学习 > 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<<")"; 
    } 

结果:
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,