矩阵连乘问题

来源:互联网 发布:cx域名哪的 编辑:程序博客网 时间:2024/04/28 16:59

矩阵连乘问题解题报告

 

1.分析最优解的结构
       将矩阵乘积A(i)*A(i+1)*...*A(j)记为A[i:j],则原问题为计算A[1:n]的最有计算次序。
     假设在A(k)和A(k+1)之间将矩阵链断开,其中1 <= k < n,则其相应的完全加括号式为(A(1)...A(k))*(A(k+1)...A(n)),

则依此计算顺序总计算量为计算A[1:k]的计算量加上计算A[k+1:n]的计算量再加上A[1:k]和A[k+1:n]相乘的计算量,其中两个矩阵( 如A(p)和A(q) )相乘的计算量为Row(p)*Col(p)*Col(q),其中Row(q)与Col(p)相等。

       这个问题的一个关键特征是:计算A[1:n]的最优次序所包含的计算矩阵A[1:k]和A[k+1:n]的次序也是最优的,因此矩阵连乘积计算次序问题的最优解包含着其子问题的最优解,这是用动态规划算法求解的显著特征。

 

2.建立递归关系
     假设计算A[i:j],其中1<=i<=j<=n,所需的最少数乘次数为m[i][j],则原问题的最优解为m[1][n],
        当i=j时,即单一矩阵连乘时,无需计算m[i][i] = 0, i = 1, 2, 3, ...,n。
        当i<j时,m[i][j] = min{ m[i][k] + m[k+1][j] + Row(i:k)*Col(i:k)*Col(k+1:j) },其中k的位置为从i到 j-1共j-i种可能。
     设数组p[n],其中p[i]表示矩阵A(i)的列数,则m[i][j]可递归地定义为
m[i][j] = 0 / min{ m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j] },

因为矩阵A[i:k]的行数等于矩阵A[i-1]的列数,矩阵A[k+1:j]的列数等于矩阵A[j]的列数。
     因此m[i][j]给出了最优解,且确定了计算A[i:j]的最优次序中的断开位置k,将断开位置k记为s[i][j],在计算出最优值m[i][j]后,可递归地由s[i][j]够造出相应的最优解。

 

3.计算最优值
     由上述可见,在递归计算时,许多子问题被重复计算多次,因此可在计算过程中保存已解决的子问题答案,每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免了大量的重复计算。


主要算法程序如下:

 

//p数组表示每个矩阵的列数
//m[i][j]表示计算A[i:j]所需最少数乘次数
void matrixChain(int n, int *p, int **m, int **s)
{


 //单一矩阵时,无需计算,因此m[i][i] = 0
 for(int i = 1; i <= n; i++)
  m[i][i] = 0;

 

 //r表示链长,从2到n
 for(int r = 2; r <= n; r++)
 {
  //链的起始位置
  for(int i = 1; i <= n; i++)
  {
   //链的结束位置
   int j = i + r - 1;
   
   //以i为断开点
   m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j];
   s[i][j] = i;

   //以k为断开点,其中k从i+1到j-1
   for(int k = i + 1; k < j; k++)
   {
    int temp = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
    if(temp < m[i][j])
    {
     m[i][j] = temp;
     s[i][j] = k;
    }
   }
  }

 }

}

 

4.构造最优解
     算法matrixChain只是计算出了最优值,但未给出最优解,事实上matrixChain已记录了构造最优解所需要的全部信息。

     s[i][j]中的数表明,计算矩阵链A[i:j]的最佳方式应在矩阵A(k)和矩阵A(k+1)之间断开,因此可递推得A[1:n]的最优完全加括号方式,即构造出问题的一个最优解。

 


主要算法程序如下:


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);
 printf("链应该断在k = %d 的位置上/n", s[i][j]);
}
}

 

 


原创粉丝点击