【动态规划】矩阵链乘法——算法设计与分析


一、问题定义

1.1 矩阵乘法

对于矩阵 U p × q U_{p\times q} Up×q V q × r V_{q\times r} Vq×r Z p × r = U V Z_{p\times r}=UV Zp×r=UV,共需计算 p q r pqr pqr次标量乘法,时间复杂度为 Θ ( p q r ) \Theta (pqr) Θ(pqr)

矩阵乘法满足结合律,即 ( U V ) W = U ( V W ) (UV)W=U(VW) (UV)W=U(VW),选择不同的结合顺序,会对计算的次数产生巨大的影响。


1.2 矩阵链乘法问题

n n n个矩阵相乘称为矩阵链乘法,问题在于如何确定相乘顺序,以提高计算效率?

形式化定义如下:

输入:

  • n n n个矩阵组成的矩阵链 U 1.. n = < U 1 , U 2 , . . . , U n > U_{1..n}=<U_1,U_2,...,U_n> U1..n=<U1,U2,...,Un>
  • 矩阵链 U 1.. n U_{1..n} U1..n对应的维度数分别为 p 0 , p 1 , . . . , p n p_0,p_1,...,p_n p0,p1,...,pn U i U_i Ui的维度为 p i − 1 × p i p_{i-1}\times p_i pi1×pi

输出:

  • 找到一种添加括号的方式,以确定矩阵链乘法的计算顺序,使得最小化矩阵链标量乘法的次数


二、求解策略

显然,最优矩阵链乘法加括号的组合中,任意一部分均为最优,具有最优子结构性质,尝试动态规划求解。


2.1 分析问题结构

形式化表示问题:

  • D [ i , j ] D[i,j] D[i,j]:计算矩阵链 U i . . j U_{i..j} Ui..j所需标量乘法的最小次数

原问题:

  • D [ i , n ] D[i,n] D[i,n]:计算矩阵链 U 1.. n U_{1..n} U1..n所需标量乘法的最小次数

2.2 建立递推关系

以长度为4的矩阵链为例辅助思考, U = U 1 U 2 U 3 U 4 U=U_1U_2U_3U_4 U=U1U2U3U4

对其进行加1个括号的操作,有以下几种方式:
U = ( U 1 ) ( U 2 U 3 U 4 ) ⇒ D [ 1 , 4 ] = D [ 1 , 1 ] + D [ 2 , 4 ] + p 0 p 1 p 4 U = ( U 1 U 2 ) ( U 3 U 4 ) ⇒ D [ 1 , 4 ] = D [ 1 , 2 ] + D [ 3 , 4 ] + p 0 p 2 p 4 U = ( U 1 U 2 U 3 ) ( U 4 ) ⇒ D [ 1 , 4 ] = D [ 1 , 3 ] + D [ 4 , 4 ] + p 0 p 3 p 4 U=(U_1)(U_2U_3U_4)\Rightarrow D[1,4]=D[1,1]+D[2,4]+p_0p_1p_4\\ U=(U_1U_2)(U_3U_4)\Rightarrow D[1,4]=D[1,2]+D[3,4]+p_0p_2p_4\\ U=(U_1U_2U_3)(U_4)\Rightarrow D[1,4]=D[1,3]+D[4,4]+p_0p_3p_4 U=(U1)(U2U3U4)D[1,4]=D[1,1]+D[2,4]+p0p1p4U=(U1U2)(U3U4)D[1,4]=D[1,2]+D[3,4]+p0p2p4U=(U1U2U3)(U4)D[1,4]=D[1,3]+D[4,4]+p0p3p4
D [ 1 , 4 ] D[1,4] D[1,4]结果只需要在这3种方式中取得最大值即可。

我们不妨来看一下,求得 D [ 1 , 4 ] D[1,4] D[1,4]需要哪些数据:

1234
1目标
2
3
4

再次观察,对角线上的元素表示矩阵自身,不需要进行运算,所以值均为0。而左下三角的矩阵并没有实际含义,因为 j ≥ i j\ge i ji,故当前表格更新为下表所示:

1234
10目标
2NULL0
3NULLNULL0
4NULLNULLNULL0

相信大家已经看出递推关系。

对于矩阵链 U i . . j U_{i..j} Ui..j,求解 D [ i , j ] D[i,j] D[i,j]时,为了不遗漏最优分割位置,需要枚举所有可能位置 i , i + 1 , . . , j − 1 i,i+1,..,j-1 i,i+1,..,j1,一共 j − i j-i ji种。

假设在 k k k处进行分割,分为 U i . . k U_{i..k} Ui..k U k + 1.. j U_{k+1..j} Uk+1..j两部分,前者的维度为 p i − 1 × p k p_{i-1} \times p_k pi1×pk,后者的维度为 p k × p j p_k\times p_j pk×pj,将两部分进行乘积时,需要额外增加 p i − 1 × p k × p j p_{i-1}\times p_k \times p_j pi1×pk×pj的计算次数。

因此, D [ i , j ] = min ⁡ i ≤ k < j { D [ i , k ] + D [ k + 1 , j ] + p i − 1 p k p j } D[i,j]=\min_{i\leq k <j} \left \{ D[i,k]+D[k+1,j]+p_{i-1}p_kp_j \right \} D[i,j]=minik<j{D[i,k]+D[k+1,j]+pi1pkpj}


2.3 自底向上计算

采用图中的方向进行计算:

在这里插入图片描述

许多教材中习惯将其逆时针旋转45度,以方便观察,在于个人习惯。

在这里插入图片描述


2.4 追踪最优方案

构造追踪数组 R e c [ 1.. n , 1.. n ] Rec[1..n,1..n] Rec[1..n,1..n] R e c [ i , j ] Rec[i,j] Rec[i,j]表示矩阵链 U i . . j U_{i..j} Ui..j的最优分割位置(一次分割)。

在计算 D [ i , j ] D[i,j] D[i,j]的过程中,选出最小的 k k k,记录 R e c [ i , j ] = k Rec[i,j]=k Rec[i,j]=k

追踪时,从 R e c [ 1 , n ] Rec[1,n] Rec[1,n]出发,假设 R e c [ 1 , n ] = k Rec[1,n]=k Rec[1,n]=k,则说明在 U k U_k Uk处进行了分割,分为矩阵链 D [ 1 , k ] D[1,k] D[1,k] D [ k + 1 , n ] D[k+1,n] D[k+1,n],再分别查看 R e c [ 1 , k ] Rec[1,k] Rec[1,k] R e c [ k + 1 , n ] Rec[k+1,n] Rec[k+1,n],便找到两部分的分割地方。如此寻找直至对角线部分。

在这里插入图片描述

在这里插入图片描述



三、算法分析

3.1 伪代码

计算及记录部分:

在这里插入图片描述

在这里插入图片描述

追踪方案部分:

在这里插入图片描述


3.2 时间复杂度

时间复杂度 O ( n 3 ) O(n^3) O(n3)

在这里插入图片描述

  • 3
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
动态规划矩阵乘法问题是指给定一系列矩阵,求解它们相乘的最少乘法次数。根据引用\[2\]中的解释,我们可以使用一个二维数组m来表示矩阵相乘所需要的最少乘法次数。其中,m\[i, j\]表示从矩阵i到矩阵j相乘所需要的最少乘法次数。 根据引用\[3\]中的思路,当只有一个矩阵时,乘法次数为0;当有两个矩阵时,乘法次数为矩阵行列直接相乘的结果。对于三个及以上的矩阵,我们可以通过动态规划的方式来求解最少乘法次数。 具体的动态规划算法如下: 1. 初始化二维数组m的对角线元素为0,表示只有一个矩阵时的乘法次数为0。 2. 从长d=2开始,逐步增加长,计算m\[i, j\]的值。对于每个长d,遍历所有可能的分割点k,计算m\[i, j\]的值。具体计算方式为:m\[i, j\] = min{m\[i, k\] + m\[k+1, j\] + a\[i\]*a\[k\]*a\[j+1\]},其中a\[i\]表示第i个矩阵的行数,a\[j+1\]表示第j+1个矩阵的列数。 3. 最终,m\[1, n\]即为所求的最少乘法次数,其中n为矩阵的长度。 通过以上算法,我们可以得到矩阵相乘的最少乘法次数。这个问题动态规划解法可以有效地减少重复计算,提高计算效率。 #### 引用[.reference_title] - *1* *2* *3* [动态规划——矩阵相乘](https://blog.csdn.net/Wu_L7/article/details/124327310)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

友人帐_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值