关键优势:当需要求解多个具有相同系数矩阵 A 但不同右端向量的方程组时,LUP 分解只需执行一次,后续每次求解仅需 Θ(n²)。
flowchart LR
A["输入: A, b"] --> B["LUP-DECOMPOSITION<br/>得到 L, U, P<br/>Θ(n³)"]
B --> C["计算 Pb"]
C --> D["前代: Ly = Pb<br/>得到 y<br/>Θ(n²)"]
D --> E["回代: Ux = y<br/>得到 x<br/>Θ(n²)"]
E --> F["输出: 解向量 x"]
2.6 LUP-SOLVE 伪代码
LUP-SOLVE(L, U, π, b)
// 输入: 单位下三角矩阵 L, 上三角矩阵 U, 置换向量 π, 右端向量 b
// 输出: 方程组 Ax = b 的解 x,其中 PA = LU, π 记录了 P 的置换信息
// π[i] = k 表示 P 的第 i 行是 I 的第 k 行
n ← L.rows
// 步骤一: 计算 Pb,同时执行前代求解 Ly = Pb
for i ← 1 to n
x[i] ← b[π[i]] // 置换 b 的第 i 个分量
for j ← 1 to i - 1
x[i] ← x[i] - L[i][j] × x[j]
// 步骤二: 回代求解 Ux = y(此时 x 中存储的是 y)
for i ← n downto 1
for j ← i + 1 to n
x[i] ← x[i] - U[i][j] × x[j]
x[i] ← x[i] / U[i][i]
return x
代码解读:
第 5-8 行:将置换和前代合并在一起。x[i] ← b[π[i]] 完成了对 b 的置换,内层循环完成前代。
第 9-13 行:回代阶段,从最后一个分量 xn 开始,逐步向前求解。
注意第 13 行的除法 x[i] / U[i][i],这里要求 U[i][i]=0,即矩阵 A 必须是非奇异的。
2.7 LUP-DECOMPOSITION 伪代码
LUP-DECOMPOSITION(A)
// 输入: n×n 矩阵 A
// 输出: 单位下三角矩阵 L, 上三角矩阵 U, 置换向量 π
// 满足 PA = LU,其中 P 由 π 确定
n ← A.rows
// 初始化 π 为恒等置换
for i ← 1 to n
π[i] ← i
// 将 A 复制到 U(后续原地修改)
for i ← 1 to n
for j ← 1 to n
U[i][j] ← A[i][j]
// 初始化 L 为单位矩阵
for i ← 1 to n
for j ← 1 to n
if i = j
L[i][j] ← 1
else
L[i][j] ← 0
// 主消元循环
for k ← 1 to n
// 部分主元选取: 在第 k 列中找到绝对值最大的元素
k' ← k
for i ← k + 1 to n
if |U[i][k]| > |U[k'][k]|
k' ← i
// 交换行: U 的第 k 行与第 k' 行互换
if k' ≠ k
swap U[k][1..n] ↔ U[k'][1..n]
swap π[k] ↔ π[k']
swap L[k][1..k-1] ↔ L[k'][1..k-1]
// 消元: 将第 k 列对角线以下元素消为零
for i ← k + 1 to n
// 计算乘数(存储在 L 中)
L[i][k] ← U[i][k] / U[k][k]
// 更新 U 的第 i 行
for j ← k + 1 to n
U[i][j] ← U[i][j] - L[i][k] × U[k][j]
// 将 U[i][k] 设为 0(消元完成)
U[i][k] ← 0
return (L, U, π)
代码解读:
第 3-4 行:初始化置换向量 π 为恒等置换 (1,2,…,n)。
第 5-10 行:将 A 复制到 U,初始化 L 为单位矩阵。
第 12-16 行:部分主元选取(partial pivoting),在第 k 列的第 k 行到第 n 行中,找到绝对值最大的元素 U[k′][k],将其所在行 k′ 与第 k 行交换。这一步保证了 ∣L[i][k]∣≤1,从而提高数值稳定性。
第 17-20 行:交换操作同时作用于 U(完整行)、π(置换记录)和 L(已计算的部分)。
第 22-28 行:消元操作,计算乘数 L[i][k]=U[i][k]/U[k][k] 并存储在 L 中,然后更新 U 的子矩阵。
【第一步(LUP 分解的等价性)】 由 LUP-DECOMPOSITION 的正确性(此处假设分解过程正确),我们有 PA=LU。由于 A 是非奇异矩阵,P 是置换矩阵(也是非奇异的),因此 PA 也是非奇异的。又因为 PA=LU,所以 L 和 U 都是非奇异的(L 的行列式为 1,U 的行列式为 ∏i=1nuii=0)。
【第二步(前代求解的正确性)】 LUP-SOLVE 的第 5-8 行求解 Ly=Pb。由于 L 是单位下三角矩阵,L 的对角线元素全为 1,因此 L 一定非奇异。根据线性代数的基本理论,下三角方程组 Ly=Pb 有唯一解 y。前代过程从 y1 开始逐个求解,每一步都是确定性的,因此得到的 y 确实是 Ly=Pb 的唯一解。
【第三步(回代求解的正确性)】 LUP-SOLVE 的第 9-13 行求解 Ux=y。由于 U 是上三角矩阵且 U 非奇异(所有对角线元素 uii=0),上三角方程组 Ux=y 有唯一解 x。回代过程从 xn 开始逐个向前求解,每一步都是确定性的,因此得到的 x 确实是 Ux=y 的唯一解。
【第四步(验证 x 满足原方程组)】 将上述两步的结果组合:
LUx=L(Ux)=Ly=Pb
因此:
LUx=Pb
又因为 PA=LU,所以:
PAx=LUx=Pb
两边左乘 P−1(由于 P 是置换矩阵,P−1=PT):
Ax=P−1Pb=b
【结论(唯一性)】 由于 A 是非奇异矩阵,方程组 Ax=b 有且仅有一个解。我们已证明 LUP-SOLVE 返回的 x 满足 Ax=b,因此 x 就是原方程组的唯一解。■
尽管理论上存在不稳定的极端情况,但在实际应用中,高斯消元(带部分主元选取)表现出极好的数值稳定性。Trefethen 和 Bau 在其经典教材中指出:“Gaussian elimination with partial pivoting is explosively unstable for certain matrices, yet stable in practice. This apparent paradox has a statistical explanation.”
完全主元选取(complete pivoting)在所有剩余子矩阵中(而非仅在第 k 列中)选择绝对值最大的元素,同时交换行和列。完全主元选取的增长因子上界更紧(ρ≤n1/2(2⋅31/2⋅⋯⋅n1/(n−1))1/2),但计算成本更高(需要 O(n3) 次比较 vs. 部分主元的 O(n2) 次),因此在实践中部分主元选取是更常用的选择。
参考来源:Lloyd N. Trefethen and David Bau III, Numerical Linear Algebra, SIAM, 1997; Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms, SIAM, 2002.
LUP-SOLVE-CHECK(L, U, π, b)
n ← L.rows
// 前代(与原版相同)
for i ← 1 to n
x[i] ← b[π[i]]
for j ← 1 to i - 1
x[i] ← x[i] - L[i][j] × x[j]
// 回代(增加奇异检测)
for i ← n downto 1
for j ← i + 1 to n
x[i] ← x[i] - U[i][j] × x[j]
if U[i][i] = 0
// 检查是否一致(即 x[i] 是否也为 0)
if x[i] ≠ 0
error "方程组无解(不一致)"
else
x[i] ← 0 // 自由变量,设为 0(或任意值)
else
x[i] ← x[i] / U[i][i]
return x
先观看 3Blue1Brown Essence of Linear Algebra 系列,建立线性代数的几何直觉
再观看 MIT 18.06 Lecture 2 和 Lecture 4,理解消元法和 LU 分解的计算过程
最后阅读 CLRS 本节内容,掌握算法的伪代码实现和复杂度分析
教材原文
CLRS 第4版 第28.1节
“We can regard the operation of solving a system of linear equations as a two-stage process. In the first stage, we compute an LUP decomposition of the coefficient matrix A. In the second stage, we solve the resulting triangular systems Ly=Pb by forward substitution and Ux=y by back substitution. The LUP decomposition is the most common way to solve systems of linear equations in practice.”
“The key idea is that we can solve Ax=b by first solving Ly=Pb and then solving Ux=y. Since L and U are triangular, both of these systems can be solved in Θ(n2) time.”