算法找到了矩阵链相乘的最低成本。
给定一个行数为
p
,列数为
q
的矩阵
A
,和一个行数为
q
,列数为
r
的矩阵
B
,标准矩阵乘法
A·B
需要进行
p*q*r
次乘法 - 对于乘积的每个
p×r
元素,需要对应行的
A
元素和对应列的
B
元素进行
q
次乘法。
现在,矩阵乘法是结合律的,因此您可以将乘积括起来。
M_1 · M_2 · … · M_n
随便怎么做,结果总是相同的。
现在,设r_0
为M_1
的行数,r_i
为M_i
的列数(也必须是M_(i+1)
的行数才能定义乘积)。
那么M_i · … · M_k
是一个r_(i-1)×r_k
矩阵,M_(k+1) · … · M_j
是一个r_k×r_j
矩阵。因此,如果通过先计算M_i · … · M_k
和M_(k+1) · … · M_j
的乘积,然后将两个结果矩阵相乘来计算乘积M_i · … · M_j
,则乘法的总成本为
c_{i,k} + c_{k+1,j} + r_(i-1)×r_k×r_j
其中c_{i,k}
表示计算M_i · … · M_k
的所选方式的成本(对于c_{k+1,j}
也是如此)。
现在,通过在M_k
后分割来评估M_i · … · M_j
的最小成本显然可以通过以最小成本计算两个子乘积来实现。
而评估M_i · … · M_j
的最小成本是通过计算所有可能分割的最小成本来找到的,因此为:
m_{i,j} = min { m_{i,k} + m_{k+1,j} + r_(i-1)×r_k×r_j : i <= k < j }
对于 i < j
,需要进行翻译。
然后,首先计算仅涉及两个矩阵的子产品的最小成本[其中只有一个可能的拆分],然后计算涉及三个矩阵的子产品的最小成本,为此需要计算仅涉及两个矩阵的子产品的最小成本 - 这就是括号化发挥作用的地方,并且通常会产生差异 - 然后四个等等,直到找到总计算的最小成本。
要找到产生最低成本的括号化,可以搜索最小成本数组以定位产生它的拆分[然后是两个子产品等等],但最好将产生最小成本的拆分位置的信息与m
数组中的最小成本一起存储。