动态规划详解(第三讲)——矩阵链相乘

这类题目体现了DP的实质,也是经典问题。(•̀˓◞•́)

假设我们要用标准的矩阵乘法计算 M1 M 1 M2 M 2 M3 M 3 的乘积 M1M2M3 M 1 M 2 M 3 ,这三个矩阵的维数分别是2x10,10x2,2x10。

  • 如果我们先把 M1 M 1 M2 M 2 相乘,然后把结果和 M3 M 3 相乘,即 M1M2M3 ( ( M 1 M 2 ) M 3 ) 。那么要进行2x10x2+2x2x10=80次乘法;
  • 如果我们先乘 M2 M 2 M3 M 3 ,结果再与 M1 M 1 相乘,即 M1M2M3 ( M 1 ( M 2 M 3 ) ) 。那么数量乘法的次数就变成了:10x2x10+2x10x10=400。

可见,矩阵链相乘时的顺序不同,运算量也不同。而我们的目的是找到一种乘法顺序使得运算量最小。


递推关系式

        我们注意到,对于矩阵链 M1M2...Mi M 1 M 2 . . . M i ,矩阵 Mi M i 的列数一定等于矩阵 Mi+1 M i + 1 的行数( 1i<n 1 ≤ i < n ),这是由矩阵乘法的定义决定的。
        因此,对于一个矩阵链,我们指定每个矩阵的行数和最右面矩阵 Mn M n 的列数就可以了。假设有n+1维数 r1,r2,...,rn+1 r 1 , r 2 , . . . , r n + 1 ,这里 ri r i 表示矩阵 Mi M i 的行数( 1in 1 ≤ i ≤ n ), rn+1 r n + 1 表示最矩阵 Mn M n 的列数。
        以后,我们用 Mi,j M i , j 来记 MiMi+1...Mj M i M i + 1 . . . M j 的乘积。用 C[i][j] C [ i ] [ j ] 来记录链 Mi,j M i , j 数量乘法的次数。
        对于给定的一对索引 i i j1i<jn Mi,j M i , j 可用如下方法计算:

  • k k i+1 j j 之间的一个索引,索引k把矩阵链 Mi,j M i , j 分成了两部分: Mi,k1=MiMi+1...Mk1 M i , k − 1 = M i M i + 1 . . . M k − 1 Mk,j=MkMk+1...Mj M k , j = M k M k + 1 . . . M j 。所以 Mi,j=Mi,k1Mk,j M i , j = M i , k − 1 M k , j

            用这种方法计算 Mi,j M i , j 的耗费(即数量乘法的次数),是计算 Mi,k1 M i , k − 1 的耗费加上计算 Mk,j M k , j 的耗费再加上 Mi,k1 M i , k − 1 乘以 Mk,j M k , j 的耗费(它是 rirkrj+1 r i r k r j + 1 )。

    我们需要遍历 k k ,找到使乘法MiMi+1...Mj所需的数量乘法最小的 k k 值,我们有以下递推式:

    C[i][j]= Mini<kj M i n i < k ≤ j {C[i][k1]+C[k][j]+rirkrj+1} { C [ i ] [ k − 1 ] + C [ k ] [ j ] + r i r k r j + 1 }

        为了找出 M1M2..Mn M 1 M 2 . . M n 的乘法次数,我们只需要解递推式:

C[1][n]= C [ 1 ] [ n ] = Min1<kn M i n 1 < k ≤ n {C[1][k1]+C[k][n]+rirkrn+1} { C [ 1 ] [ k − 1 ] + C [ k ] [ n ] + r i r k r n + 1 }

填表

假设我们要求 n=6 n = 6 个矩阵相乘。考虑下图:
这里写图片描述

对角线 d d 用乘出各种d+1个相继矩阵的最小耗费填满。特别地,对角线5恰好由一项组成,它表示6个矩阵相乘的最小耗费,这就是我们要求的结果。
我们从对角线0开始,到对角线5为止,沿着对角线填充这个三角形表。

  • 首先在对角线0中,每个链仅由一个矩阵的组成,没有数量乘法,因此这个对角线填0。
  • 接着,对角线1由两个连续的矩阵相乘的耗费来填充。如C[2][3]用 M2M3 M 2 M 3 的乘法耗费来填。
  • 余下的对角线根据上面的递推式和先前存储在表中值来填。举例来说,C[2][5]的值为以下三个耗费的最小值:
    – (1)计算 M2,2 M 2 , 2 的耗费(即C[2][2])加上计算 M3,5 M 3 , 5 (即C[3][5])的耗费,再加上 M2,2 M 2 , 2 乘以 M3,5 M 3 , 5 的耗费。
    – (2)计算 M2,3 M 2 , 3 的耗费(即C[2][3])加上计算 M4,5 M 4 , 5 (即C[4][5])的耗费,再加上 M2,3 M 2 , 3 乘以 M4,5 M 4 , 5 的耗费。
    – (3)计算 M2,4 M 2 , 4 的耗费(即C[2][4])加上计算 M5,5 M 5 , 5 (即C[5][5])的耗费,再加上 M2,4 M 2 , 4 乘以 M5,5 M 5 , 5 的耗费。

伪代码

下面我们给出算法的伪代码实现
MATCHAIN
输入:n个矩阵的链的维数对应于正整数数组 r[1...n+1] r [ 1... n + 1 ] ,其中, r[1...n] r [ 1... n ] 是n个矩阵的行数, r[n+1] r [ n + 1 ] Mn M n 的列数。
输出:n个矩阵相乘的数量乘法的最小次数。

for i=1 to n {填充对角线d0}
    C[i,i]=0;
end for
for d=1 to n-1 {填充对角线d1到dn-1}
    for i=1 to n-d {填充对角线di的项目}
        j=i+d
        comment:下列三行计算C[i,j]
        C[i,j]=inf
        for k=i+1 to j
            C[i,j]=Min{C[i,j],C[i,k-1]+C[k,j]+r[i]*r[k]*[j+1]
        end for
    end for
end for
return C[1,n]


时空复杂度

对于某个常数c>0,算法的运行时间正比于:

d=1n1i=1ndk=1dc=cn3cn6 ∑ d = 1 n − 1 ∑ i = 1 n − d ∑ k = 1 d c = c n 3 − c n 6

因此算法的时间复杂度是 Θ(n3) Θ ( n 3 )

显然,算法所需要的内存空间取决于所需要的三角数组的大小,也就是 Θ(n2 Θ ( n 2 )

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值