算法导论—矩阵链乘法(动态规划)

40 篇文章 6 订阅

矩阵链乘法

矩阵相乘

矩阵相乘的括号化方案

设有四个矩阵 A 、 B 、 C 、 D A、B、C、D ABCD,它们的维数分别是:
A = 50 ∗ 10 、 B = 10 ∗ 40 、 C = 40 ∗ 30 、 D = 30 ∗ 5 A=50*10、B=10*40、C=40*30、D=30*5 A=5010B=1040C=4030D=305总共有五种完全加括号的方式,如下:
( A ( ( B C ) D ) ) 、 ( A ( B ( C D ) ) ) 、 ( ( A B ) ( C D ) ) 、 ( ( ( A B ) C ) D ) 、 ( ( A ( B C ) ) D ) . (A((BC)D))、(A(B(CD)))、\\((AB)(CD))、(((AB)C)D)、((A(BC))D). (A((BC)D))(A(B(CD)))((AB)(CD))(((AB)C)D)((A(BC))D).

不同计算代价

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

应用动态规划方法的步骤

  1. 刻划一个最优解的结构特征;
  2. 递归地定义最优解的值;
  3. 计算最优解的值,通常采用自底向上的方法;
  4. 利用计算出的信息构造一个最优解。

按照步骤分析问题

步骤 1 1 1:最优括号化方案的结构特征
我们用符号 A i ⋅ j ( i < = j ) Ai·j (i<=j) Aij(i<=j)表示 A i A i + 1 ⋅ ⋅ ⋅ A j AiAi+1···Aj AiAi+1⋅⋅⋅Aj乘积的结果矩阵,如果问题是非凡的,即 i < j i<j i<j,那么为了对 A i A i + 1 ⋅ ⋅ ⋅ A j AiAi+1···Aj AiAi+1⋅⋅⋅Aj进行括号化,我们就必须在某个 A k Ak Ak A k + 1 Ak+1 Ak+1之间将矩阵链划分开( k k k i ≤ k < j i\le k<j ik<j之间的整数),也就是说我们首先计算矩阵 A i ⋅ ⋅ ⋅ k Ai···k Ai⋅⋅⋅k A k + 1 ⋅ ⋅ ⋅ j Ak+1···j Ak+1⋅⋅⋅j,然后再计算他们的乘积得到最终结果 A i ⋅ ⋅ ⋅ j Ai···j Ai⋅⋅⋅j。现在问题就变成了对矩阵 A i ⋅ ⋅ ⋅ k Ai···k Ai⋅⋅⋅k A k + 1 ⋅ ⋅ ⋅ j Ak+1···j Ak+1⋅⋅⋅j进行独立求解,并且要满足最优括号化方案,最后将子问题的最优解合并就可以得到问题的最优解。

步骤 2 2 2:一个递归求解方案
m [ i , j ] m[i,j] m[i,j]表示计算矩阵 A i ⋅ ⋅ ⋅ j Ai···j Ai⋅⋅⋅j数乘次数的最小值,那么原问题的最优解——计算 A 1 ⋅ ⋅ ⋅ n A_{1···n} A1⋅⋅⋅n所需的最低代价就是 m [ 1 , n ] m[1,n] m[1,n] i = j i=j i=j时不需要做任何标量乘法运算,所以 m [ i , i ] = 0 m[i,i]=0 m[i,i]=0。若 i < j i<j i<j,利用步骤 1 1 1中得到的最优子结构来计算 m [ i , j ] m[i,j] m[i,j]。设矩阵Ai···j 的大小为pi-1×pi ,那么 A i ⋅ ⋅ ⋅ k A_{i···k} Ai⋅⋅⋅k A k + 1 ⋅ ⋅ ⋅ j A_{k+1···j} Ak+1⋅⋅⋅j相乘的代价为 p i − 1 ∗ p k ∗ p j p_{i-1}*p_k*p_j pi1pkpj。因此可得.
m [ i , j ] = m [ i , k ] + m [ k + 1 , j ] + p i − 1 p k p j . m[i,j] = m[i,k]+ m[k+1,j]+p_{i-1} p_kp_j. m[i,j]=m[i,k]+m[k+1,j]+pi1pkpj.
此递归公式假定最优分割点 k k k是已知的,但实际上我们并不知道。不过, k k k只有 j − i j-i ji种可能的取值,即 k = i , i + 1 , ⋅ ⋅ ⋅ , j − 1 k=i,i+1,···,j-1 k=ii+1⋅⋅⋅j1.由于最优分割点必其中,我们只需要检查所有可能的情况,推到最优者即可。因此, A i A i + 1 ⋅ ⋅ ⋅ A j A_iA_{i+1}···A_j AiAi+1⋅⋅⋅Aj 最小代价括号化方案的递归求解公式变为
在这里插入图片描述

伪代码

MATRIX-CHAIN-ORDER(p)
    n=p.length-1
    let m[1..n][1..n] and s[1..n-1][2..n] be new tables
    for i=1 to n
        m[i][i]=0 // 也就是把二维数组m中主对角线元素置为0
    for l=2 to n   // l is the chain lenth(即 2个矩阵相乘,3个相乘,...n个相乘)
        for i=1 to n-l+1 // 控制行的变换,可以把数组m在纸上画出来,发现i是控制对角线上的行变换。
            j=i+l-1 //即j=i+(l-1), 本来主对角线上是j=i的,但是,当矩阵链为l时,列(即j)右移(l-1)位,所以j=i+(l-1),也就是控制列的变化
            m[i][j]=for k=i to j-1
                q=m[i] [k]+m[k+1] [j]+p[i-1]p[k]p[j]
                if q< m[i][j]
                    m[i][j]=q
                    s[i][j]=k
    return m and s

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之墨_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值