矩阵链乘法

概述

矩阵链乘法问题是动态规划的经典范例:给定 个矩阵的链,求完全括号化方案使标量乘法次数最少。该问题展示了最优子结构的典型应用——最优括号化在某个位置分裂后,左右两段也必须是最优括号化的。

定义

矩阵链乘法问题(Matrix-Chain Multiplication)

输入:矩阵链 ,其中 的维度为

输出:一个完全括号化方案,使得计算矩阵链乘积所需的标量乘法次数最少。

为计算 所需的最少标量乘法次数,则:

其中 是在位置 分裂后,将两个子结果矩阵相乘的代价。

核心性质

1. 最优子结构

的最优括号化在 之间分裂。则子链 的括号化方案必须是计算该子链的最优方案, 同理。

证明(反证法):若 存在代价更小的括号化方案,将其替换到原方案中,可得到 的代价更小的括号化方案——与最优性矛盾。

2. 自底向上计算

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
    for l = 2 to n:                    // l 为链长度
        for i = 1 to n - 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

3. 构造最优解

通过 表递归构造最优括号化方案:

PRINT-OPTIMAL-PARENS(s, i, j):
    if i == j:
        print "A" + i
    else:
        print "("
        PRINT-OPTIMAL-PARENS(s, i, s[i,j])
        PRINT-OPTIMAL-PARENS(s, s[i,j]+1, j)
        print ")"

4. 子问题总数与计算顺序

  • 子问题总数: 个(即所有满足 对)
  • 每个子问题需要遍历 个分裂点
  • 总时间复杂度:
  • 空间复杂度: 表和 表各占

5. 计算顺序示例

对于 个矩阵,计算顺序按链长度递增:

  1. 长度 2:
  2. 长度 3:
  3. 长度 4:

这确保了计算 时,所有更短的子问题 已经计算完毕。

复杂度分析

指标
时间复杂度
空间复杂度
子问题数量

章节扩展

参见