动态规划之矩阵连乘积问题

如果对动态规划概念不懂的同学请看这里动态规划原理
矩阵连乘积问题
m X n矩阵A与n X p矩阵B相乘需耗费的时间。
我们把mnp作为两个矩阵相乘所需时间的测量值。
现在假设三个矩阵A、B和C的乘积,有两种方式计算此乘积,那么有(AB)C和A(BC)两种方式计算此乘积。尽管两种不同的计算顺序所得的结果是相同的,但时间消耗会有很大差距。
在这里插入图片描述
矩阵连乘积问题定义:
给定n个矩阵{A1,A2,A3,……,An},其中Ai与Ai+1是可乘的,i=1,2,……n-1。考察这n个矩阵的连乘积A1A2A3……An。

  • 由于矩阵乘法满足结合律,所以计算矩阵的连乘积可以有许多不同的计算次序。
  • 这种次序可以加括号的方式来确定。
  • 若一个矩阵连乘积的计算机次序完全确定,也就是说该连乘积已完全加括号,则可反复调用2个矩阵相乘的标准算法来计算出矩阵连乘积
    以四矩阵个为例
    在这里插入图片描述
    第一步:分析最优解的结构
  • 将矩阵连乘积AiAi+1…Aj简记为A[i:j],这里i<=j;
  • 考察计算A[1:n]的最优计算次序。
    • 设这个计算次序在矩阵Ak和Ak+1之间将矩阵链断开,1<=K<n,则其相应完全加括号方式为(A1A2…Ak)(Ak+1Ak+2…An)
    • 计算量:A[1:k]的计算量加上A[k+1:n] 的计算量,再加上A[1:k]和A[k+1:n]相乘的计算量

第二步:建立递归关系

  • 设计算A[i:j],1<=i<=j<=n,所需要的最少数乘次数m[i,j],则原问题的最优值为m[1,n];
  • 当i=j时,A[i:j]=Ai,因此,m[i,i]=0,i=1,2,3…,n
  • 当i<j时,m[i,j]=m[i,k]+m[K+1,j]+pi-1pkpj
  • 这里Ai的维数是pi-1Xpi可以递归定义为:
    在这里插入图片描述
    计算最优解
#define NUM 51;
int p[NUM];
int m[NUM][NUM];
int s[NUM][NUM];
void MatrixChain(int n)
{
    
    
 for(int  i=1;i<=n;i++) m[i][i]=0;
 for(int  r=2;r<=n;r++)//列
    for(int l=1;l<=n-r+1;l++)//行
    {
    
    
     int j=l+r-1;
     int i=l;//初值从i开始断开
     m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
     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];
      if(t<m[i][j]){
    
    m[i][j]=t;s[i][j]=k;}
     }
   }
}
      

从d1斜线依次向上计算到d6
构造最优解
s[i][j]已经存储了构造最优解足够的信息

void TraceBook(int i,int j)
{
    
     
  if(i==j) printf("A%d",i);
  else{
    
    
   printf("(");
   TraceBack(i,s[i][j]);
   TraceBack(s[i][j]+1,j);
   printf(")");
   }
}

时间复杂度
三重O(n)循环,工作量W(n)=O(n3)
备忘录也是三重O(n)循环,工作量W(n)=O(n3)
最后追踪解工作量O(n)

猜你喜欢

转载自blog.csdn.net/qq_43515378/article/details/105100621
今日推荐