Jacobi 迭代法 (Jacobi solver)是一种经典的线性方程组迭代解法。我来详细解释它的算法原理、步骤和应用。
1. 问题设定
求解线性方程组:
其中:
是系数矩阵,非奇异
是未知向量
b∈Rn 是常数向量
Jacobi 法适用于对角占优矩阵,保证收敛性。
2. 核心思想
将矩阵 A 分解为
D : 对角矩阵,
R : 剩余矩阵 (包含所有非对角元素)
原方程:
假设 D 可逆(即所有对角元非零),则:
3. Jacobi 迭代公式
从上述推导出迭代形式。令 表示第 k 次迭代的解向量:
Jacobi 迭代公式
矩阵形式
4. 算法步骤
输入:
-
矩阵
-
右端向量
-
初始猜测
(常取零向量)
-
容差
(收敛判断)
-
最大迭代次数
输出:
- 近似解
伪代码:
1. 初始化 x_old = x0, k = 0
2. while k < N_max:
3. for i = 1 to n:
4. sum = 0
5. for j = 1 to n:
6. if j != i:
7. sum += A[i][j] * x_old[j]
8. x_new[i] = (b[i] - sum) / A[i][i]
9. 计算误差: err = ||x_new - x_old||
10. if err < ε:
11. return x_new
12. x_old = x_new
13. k = k + 1
14. 达到最大迭代次数,返回 x_new
5. 收敛条件
Jacobi 法收敛的充分条件:
(1) 严格对角占优:
(2) 谱半径条件 :
定义迭代矩阵 ,则 Jacobi 迭代收敛当且仅当:
其中 是
的谱半径(最大特征值的模)。
6. 与 Gauss-Seidel 法的对比
Jacobi 法的一个关键特点是完全并行更新:
| 特性 | Jacobi 法 | Gauss-Seidel 法 |
|---|---|---|
| 更新方式 | 使用上一轮的所有值 | 使用本轮已更新的值 |
| 公式 | ||
| 并行性 | 完全并行(所有 i 可同时计算) | 顺序依赖 |
| 收敛速度 | 通常较慢 | 通常较快 |
| 内存需求 | 需保存 |
只需一个向量 |
7. 算法复杂度
每轮迭代:
-
浮点运算次数 :
(对每个 i,求和需 n-1 次乘加)
-
内存访问 :需要读取整个矩阵 A 和向量
总复杂度:,其中 K 是迭代次数。
8. 数值示例
求解方程组:
Jacobi 迭代公式:
从 开始:
| k | x | y | z |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | 1.75 | 2.625 | 3.0 |
| 2 | 1.65625 | 3.875 | 2.9625 |
| 3 | 1.978125 | 3.925 | 2.99 |
| ... | ... | ... | ... |
| 精确解 | 2 | 4 | 3 |
9. 优缺点
优点:
-
高度并行 每个未知数的新值可独立计算
-
简单易实现
-
内存友好(相比直接法如高斯消元)
-
数值稳定 不会放大舍入误差
缺点:
-
收敛慢 特别对非对角占优矩阵
-
需要存储整个矩阵(不适合非常稀疏但非结构化矩阵)
-
可能不收敛 不满足收敛条件时发散
10. 实际应用场景
-
Poisson 方程求解(有限差分/有限元离散后)
-
热传导方程稳态解
-
大规模稀疏线性方程组(结合预处理技术)
-
并行计算环境 MPI、GPU 上容易实现
-
多物理场模拟中的线性求解器
11. 代码示例(Python)
python
import numpy as np
def jacobi_solver(A, b, x0=None, tol=1e-10, max_iter=1000):
n = len(A)
if x0 is None:
x = np.zeros(n)
else:
x = x0.copy()
x_new = np.zeros(n)
for k in range(max_iter):
for i in range(n):
# 计算非对角项求和
s = np.dot(A[i, :i], x[:i]) + np.dot(A[i, i+1:], x[i+1:])
x_new[i] = (b[i] - s) / A[i, i]
# 检查收敛
if np.linalg.norm(x_new - x) < tol:
print(f"Jacobi 收敛于第 {k+1} 次迭代")
return x_new
x = x_new.copy()
print("达到最大迭代次数")
return x
# 示例
A = np.array([[4, -1, 1],
[4, -8, 1],
[-2, 1, 5]], dtype=float)
b = np.array([7, -21, 15], dtype=float)
solution = jacobi_solver(A, b)
print("解:", solution)
print("验证 Ax-b:", np.dot(A, solution) - b)
12. 改进版本
(1) 带松弛的 Jacobi(加权 Jacobi)
其中 是松弛因子,常取
。
(2) 块 Jacobi 法
将变量分组,每组用直接法求解,组间用 Jacobi 迭代。适合块对角占优矩阵。
(3) 预处理 Jacobi
使用预处理矩阵 P 加速收敛: 。
总结
Jacobi 迭代法是基于矩阵分裂 的最简单迭代法,其核心是利用对角元解出每个变量 ,完全并行更新所有变量。虽然收敛速度通常较慢,但因其简单性和并行性,在科学计算和大规模问题中仍有重要地位,常作为更复杂算法(如多重网格法)的平滑器或预处理器。