动态规划(一)

动态规划算法基本介绍;矩阵连乘问题

Posted by kkkkuboy on February 27, 2019

动态规划(一)

动态规划基本步骤

  • 找出最优解的性质,并刻划其结构特征。
  • 递归地定义最优值。
  • 以自底向上的方式计算出最优值。
  • 根据计算最优值时得到的信息,构造最优解。

动态规划算法基本要素

  • 最优子结构:问题的最优解包含其子问题的最优解
  • 重叠子问题:递归算法求解问题时,每次产生的子并不总是新有些子问题被反复计算多次。

矩阵连乘问题

给定 n个矩阵{ A1,A 2,…,A ,…,A n},其中 Ai 与Ai+1Ai+1 Ai+1是可乘的, i=1 ,2… ,n-1。如何确定计算矩阵连乘积的次序,使得依此序计算矩阵连乘积需要的数乘次数最少。

问题理解:

给定n个矩阵{A1,A2,…,An,}, 其中Ai与Ai+1是可乘的,i=1,2,…,n-1 。考察这n个矩阵的连乘积A1A2…An

由于矩阵乘法满足结合律,所以计算矩阵的连乘可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。

若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积

最优解结构特征:

特征:计算 A[i:j] A[i:j] 的最优次序所包含计算矩阵子 的最优次序所包含计算矩阵子 链 A[i:k] A[i:k] 和A[k+1:j] A[k+1:j] 的次序也是最优的。

递归地定义最优值:

计算量(最优值):A[i:k]的计算量加上A[k+1:j]的计算量,再加上 A[i:k]和A[k+1:j]相乘的计算量。

建立递归关系:

设计算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,…,n;

当i<j时,m[i,j]=m[i,k]+m[k+1,j]+pi-1pkpj ; 这里Ai 的维数为pi-1 pi ;pi-1pkpj是因为最后结果为维度为pi-1 pj即pi-1 pj个元素,每个元素要乘pk次。(pk为k+1的行数)

可以递归地定义m[i,j]为:

m[i,j]=0(i=j);min{ m[i,k]+m[k+1,j]+pi-1pkpj }(i<j)

计算最优值:

构造最优解:

void MatrixChain(int *p,int n,int **m,int **s)
{//p[i]记录Ai-1的行数,为p[j]记录Aj的列数,n为矩阵个数,m为最优值,s计算最优值得到的信息,用于计算最优解;
    for(int i=1;i<=n;i++){
        m[i][i]=0;
    }
    for(int r=2;r<nr++){
        for(int i=1;i<=n-r+1;i++){
            int j=i+r-1;//j为n
            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+1]p[j];
                if(t<m[i][j]){
                    m[i][j]=t;
                    s[i][j]=k;
                }
            }
        }
    }
}

代码实现:


复杂度分析:

算法matrixChain的主要计算量取决于算法中对r, i和k的3重循环。循环体内的计算量为O(1),而3重 循环的总次数为O(n3)。因此算法的计算时间上界 为O(n3)。算法所占用的空间显然为O(n2)。