解线性方程组的直接方法:高斯消元法与其程序实现
解线性方程组的直接方法:高斯消元法与其程序实现
1.顺序高斯消元法
设线性方程组
A
x
=
b
\boldsymbol{Ax}=\boldsymbol{b}
Ax=b
如果
a
k
k
(
k
)
≠
0
a_{kk}^{\left( k \right)}\ne 0
akk(k)=0
可以通过高斯消元法转化为等价的三角形线性方程组:
[
a
11
a
12
⋯
a
1
n
a
21
a
22
⋯
a
2
n
⋮
⋮
⋱
⋮
a
n
1
a
n
2
⋯
a
n
n
]
[
x
1
x
2
⋮
x
n
]
=
[
b
1
b
2
⋮
b
n
]
→
高斯消元法
[
a
11
(
1
)
a
12
(
1
)
⋯
a
1
n
(
1
)
0
a
22
(
2
)
⋯
a
2
n
(
2
)
⋮
⋮
⋱
⋮
0
0
⋯
a
n
n
(
n
)
]
[
x
1
x
2
⋮
x
n
]
=
[
b
1
(
1
)
b
2
(
2
)
⋮
b
n
(
n
)
]
\left[ \begin{matrix} a_{11}& a_{12}& \cdots& a_{1n}\\ a_{21}& a_{22}& \cdots& a_{2n}\\ \vdots& \vdots& \ddots& \vdots\\ a_{n1}& a_{n2}& \cdots& a_{nn}\\ \end{matrix} \right] \left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] =\left[ \begin{array}{c} b_1\\ b_2\\ \vdots\\ b_n\\ \end{array} \right] \\ \overset{\text{高斯消元法}}{\rightarrow}\left[ \begin{matrix} a_{11}^{\left( 1 \right)}& a_{12}^{\left( 1 \right)}& \cdots& a_{1n}^{\left( 1 \right)}\\ 0& a_{22}^{\left( 2 \right)}& \cdots& a_{2n}^{\left( 2 \right)}\\ \vdots& \vdots& \ddots& \vdots\\ 0& 0& \cdots& a_{nn}^{\left( n \right)}\\ \end{matrix} \right] \left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] =\left[ \begin{array}{c} b_{1}^{\left( 1 \right)}\\ b_{2}^{\left( 2 \right)}\\ \vdots\\ b_{n}^{\left( n \right)}\\ \end{array} \right]
⎣⎢⎢⎢⎡a11a21⋮an1a12a22⋮an2⋯⋯⋱⋯a1na2n⋮ann⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡b1b2⋮bn⎦⎥⎥⎥⎤→高斯消元法⎣⎢⎢⎢⎢⎡a11(1)0⋮0a12(1)a22(2)⋮0⋯⋯⋱⋯a1n(1)a2n(2)⋮ann(n)⎦⎥⎥⎥⎥⎤⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎡b1(1)b2(2)⋮bn(n)⎦⎥⎥⎥⎥⎤
2.列主元高斯消元法
由于顺序高斯消元法存在以下缺陷:
- 当线性方程组的系数行列式 ∣ A ∣ ≠ 0 \left|\boldsymbol{A}\right| \ne 0 ∣A∣=0,且存在 1 1 1个主元素为 0 0 0,线性方程组有为一解,但是顺序高斯消元法不能解出。
- 小主元可以求解但是误差比较大。
通过交换行来避免小主元和
0
0
0主元,然后继续使用消元法求解的方法,称为选主元高斯消元法
其改进之处在于:
选主元:
∣
a
p
k
(
k
)
∣
=
max
k
≤
i
≤
n
∣
a
i
k
(
k
)
∣
\left|a_{pk}^{(k)}\right| = \max_{k \le i \le n} \left|a_{ik}^{(k)}\right|
∣∣∣apk(k)∣∣∣=k≤i≤nmax∣∣∣aik(k)∣∣∣
交换行:
{
a
k
j
(
k
)
↔
a
p
j
(
k
)
,
j
=
k
,
k
+
1
,
⋯
,
n
,
b
k
(
k
)
↔
b
p
(
k
)
.
\begin{cases} a_{kj}^{(k)} \leftrightarrow a_{pj}^{(k)}, & j = k, k+1, \cdots, n, \\ b_k^{(k)} \leftrightarrow b_p^{(k)}. \end{cases}
{akj(k)↔apj(k),bk(k)↔bp(k).j=k,k+1,⋯,n,
消元公式:
m
i
k
=
a
i
k
(
k
)
a
k
k
(
k
)
,
i
=
k
+
1
,
⋯
,
n
,
m_{ik} = \frac{a_{ik}^{(k)}}{a_{kk}^{(k)}}, \quad i = k+1, \cdots, n,
mik=akk(k)aik(k),i=k+1,⋯,n,
{
a
i
j
(
k
+
1
)
=
a
i
j
(
k
)
−
m
i
k
a
k
j
(
k
)
,
i
,
j
=
k
+
1
,
⋯
,
n
,
b
i
(
k
+
1
)
=
b
i
(
k
)
−
m
i
k
b
k
(
k
)
,
i
=
k
+
1
,
⋯
,
n
.
\begin{cases} a_{ij}^{(k+1)} = a_{ij}^{(k)} - m_{ik}a_{kj}^{(k)}, & i,j = k+1, \cdots, n, \\ b_i^{(k+1)} = b_i^{(k)} - m_{ik}b_k^{(k)}, & i = k+1, \cdots, n. \end{cases}
{aij(k+1)=aij(k)−mikakj(k),bi(k+1)=bi(k)−mikbk(k),i,j=k+1,⋯,n,i=k+1,⋯,n.
3.全主元高斯消元法
列主元高斯消元法虽然在一定程度上避免了零主元和小主元带来的问题,但它仅在当前列中选取主元。而全主元高斯消元法更为严格,它在整个未处理的子矩阵中选取主元,从而能进一步减少计算误差,提高求解的稳定性。
对于线性方程组
A
x
=
b
\boldsymbol{Ax}=\boldsymbol{b}
Ax=b,其中
A
\boldsymbol{A}
A 是
n
×
n
n\times n
n×n 系数矩阵,
b
\boldsymbol{b}
b 是
n
n
n 维常数向量,求解步骤如下:
对于线性方程组
A
x
=
b
\boldsymbol{Ax}=\boldsymbol{b}
Ax=b,其中
A
\boldsymbol{A}
A 是
n
×
n
n\times n
n×n 系数矩阵,
b
\boldsymbol{b}
b 是
n
n
n 维常数向量,求解步骤如下:
步骤 1:初始化
设初始矩阵为 A ( 1 ) = A \boldsymbol{A}^{(1)}=\boldsymbol{A} A(1)=A, b ( 1 ) = b \boldsymbol{b}^{(1)}=\boldsymbol{b} b(1)=b, k = 1 k = 1 k=1。
步骤 2:选主元(在第 k k k 步)
在子矩阵
A
(
k
)
\boldsymbol{A}^{(k)}
A(k) 的右下角
(
n
−
k
+
1
)
×
(
n
−
k
+
1
)
(n - k+1)\times(n - k + 1)
(n−k+1)×(n−k+1) 子矩阵中选取绝对值最大的元素作为主元,即
∣
a
p
q
(
k
)
∣
=
max
k
≤
i
≤
n
,
k
≤
j
≤
n
∣
a
i
j
(
k
)
∣
\left|a_{p q}^{(k)}\right|=\max_{k\leq i\leq n,k\leq j\leq n}\left|a_{i j}^{(k)}\right|
∣∣∣apq(k)∣∣∣=k≤i≤n,k≤j≤nmax∣∣∣aij(k)∣∣∣
其中,
p
p
p 表示主元所在的行,
q
q
q 表示主元所在的列。
步骤 3:交换行和列
若
p
≠
k
p\neq k
p=k,交换
A
(
k
)
\boldsymbol{A}^{(k)}
A(k) 的第
k
k
k 行和第
p
p
p 行,同时交换
b
(
k
)
\boldsymbol{b}^{(k)}
b(k) 的第
k
k
k 个和第
p
p
p 个元素;若
q
≠
k
q\neq k
q=k,交换
A
(
k
)
\boldsymbol{A}^{(k)}
A(k) 的第
k
k
k 列和第
q
q
q 列。记录列交换的信息,用于后续恢复解的顺序。交换规则如下:
{
a
k
j
(
k
)
↔
a
p
j
(
k
)
,
j
=
1
,
⋯
,
n
b
k
(
k
)
↔
b
p
(
k
)
\begin{cases} a_{k j}^{(k)}\leftrightarrow a_{p j}^{(k)},&j = 1,\cdots,n\\ b_{k}^{(k)}\leftrightarrow b_{p}^{(k)} \end{cases}
{akj(k)↔apj(k),bk(k)↔bp(k)j=1,⋯,n
{
a
i
k
(
k
)
↔
a
i
q
(
k
)
,
i
=
1
,
⋯
,
n
\begin{cases} a_{i k}^{(k)}\leftrightarrow a_{i q}^{(k)},&i = 1,\cdots,n \end{cases}
{aik(k)↔aiq(k),i=1,⋯,n
步骤 4:消元计算
计算乘数:
m
i
k
=
a
i
k
(
k
)
a
k
k
(
k
)
,
i
=
k
+
1
,
⋯
,
n
m_{i k}=\frac{a_{i k}^{(k)}}{a_{k k}^{(k)}}, \quad i=k + 1,\cdots,n
mik=akk(k)aik(k),i=k+1,⋯,n
更新系数矩阵和常数向量:
{
a
i
j
(
k
+
1
)
=
a
i
j
(
k
)
−
m
i
k
a
k
j
(
k
)
,
i
=
k
+
1
,
⋯
,
n
;
j
=
k
+
1
,
⋯
,
n
b
i
(
k
+
1
)
=
b
i
(
k
)
−
m
i
k
b
k
(
k
)
,
i
=
k
+
1
,
⋯
,
n
\begin{cases} a_{i j}^{(k + 1)}=a_{i j}^{(k)}-m_{i k}a_{k j}^{(k)},&i = k + 1,\cdots,n;j = k+1,\cdots,n\\ b_{i}^{(k + 1)}=b_{i}^{(k)}-m_{i k}b_{k}^{(k)},&i = k + 1,\cdots,n \end{cases}
{aij(k+1)=aij(k)−mikakj(k),bi(k+1)=bi(k)−mikbk(k),i=k+1,⋯,n;j=k+1,⋯,ni=k+1,⋯,n
步骤 5:循环更新
令 k = k + 1 k=k + 1 k=k+1,若 k < n k\lt n k<n,返回步骤 2 继续进行;若 k = n k = n k=n,则消元过程结束。
步骤 6:回代求解
经过消元后,得到上三角方程组
A
(
n
)
x
=
b
(
n
)
\boldsymbol{A}^{(n)}\boldsymbol{x}=\boldsymbol{b}^{(n)}
A(n)x=b(n),通过回代法求解
x
\boldsymbol{x}
x。回代公式为:
x
n
=
b
n
(
n
)
a
n
n
(
n
)
x_{n}=\frac{b_{n}^{(n)}}{a_{n n}^{(n)}}
xn=ann(n)bn(n)
x
i
=
b
i
(
i
)
−
∑
j
=
i
+
1
n
a
i
j
(
i
)
x
j
a
i
i
(
i
)
,
i
=
n
−
1
,
⋯
,
1
x_{i}=\frac{b_{i}^{(i)}-\sum_{j = i+1}^{n}a_{i j}^{(i)}x_{j}}{a_{i i}^{(i)}}, \quad i=n - 1,\cdots,1
xi=aii(i)bi(i)−∑j=i+1naij(i)xj,i=n−1,⋯,1
4.高斯——若尔当消元法
以下是高斯-若尔当消元法的分步解释和公式表示:
高斯-若尔当消元法(Gauss-Jordan Elimination)
核心思想:
在消元过程中,不仅通过前向消元将系数矩阵化为上三角矩阵(如普通高斯消元法),进一步通过反向消元将矩阵化为对角矩阵或单位矩阵,从而直接得到解,无需回代。
分步矩阵变换过程
初始线性方程组(增广矩阵形式):
[
a
11
(
1
)
a
12
(
1
)
⋯
a
1
n
(
1
)
b
1
(
1
)
a
21
(
1
)
a
22
(
1
)
⋯
a
2
n
(
1
)
b
2
(
1
)
⋮
⋮
⋱
⋮
⋮
a
n
1
(
1
)
a
n
2
(
1
)
⋯
a
n
n
(
1
)
b
n
(
1
)
]
\left[\begin{array}{cccc|c} a_{11}^{(1)} & a_{12}^{(1)} & \cdots & a_{1n}^{(1)} & b_1^{(1)}\\ a_{21}^{(1)} & a_{22}^{(1)} & \cdots & a_{2n}^{(1)} & b_2^{(1)}\\ \vdots & \vdots & \ddots & \vdots & \vdots\\ a_{n1}^{(1)} & a_{n2}^{(1)} & \cdots & a_{nn}^{(1)} & b_n^{(1)} \end{array}\right]
⎣⎢⎢⎢⎢⎡a11(1)a21(1)⋮an1(1)a12(1)a22(1)⋮an2(1)⋯⋯⋱⋯a1n(1)a2n(1)⋮ann(1)b1(1)b2(1)⋮bn(1)⎦⎥⎥⎥⎥⎤
第 k k k 步消元(共 n n n 步):
- 选取主元:在第 k k k列中选取绝对值最大的元素作为主元(部分选主元法)。
- 归一化主元行:将主元所在行除以主元值,使主元位置为 1 1 1。
- 消去主元列的所有非主元元素:
- 对 i ≠ k i \neq k i=k 的所有行,用主元行消去第 k k k 列的元素,使其为 0 0 0。
分步过程:
→
第1步消元
[
1
a
12
(
2
)
⋯
a
1
n
(
2
)
b
1
(
2
)
0
a
22
(
2
)
⋯
a
2
n
(
2
)
b
2
(
2
)
⋮
⋮
⋱
⋮
⋮
0
a
n
2
(
2
)
⋯
a
n
n
(
2
)
b
n
(
2
)
]
→
第2步消元
[
1
0
⋯
a
1
n
(
3
)
b
1
(
3
)
0
1
⋯
a
2
n
(
3
)
b
2
(
3
)
⋮
⋮
⋱
⋮
⋮
0
0
⋯
a
n
n
(
3
)
b
n
(
3
)
]
⋮
→
第n步消元
[
1
0
⋯
0
b
1
(
n
+
1
)
0
1
⋯
0
b
2
(
n
+
1
)
⋮
⋮
⋱
⋮
⋮
0
0
⋯
1
b
n
(
n
+
1
)
]
\begin{aligned} &\xrightarrow{\text{第1步消元}} \begin{bmatrix} 1 & a_{12}^{(2)} & \cdots & a_{1n}^{(2)} & b_1^{(2)} \\ 0 & a_{22}^{(2)} & \cdots & a_{2n}^{(2)} & b_2^{(2)} \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & a_{n2}^{(2)} & \cdots & a_{nn}^{(2)} & b_n^{(2)} \end{bmatrix} \\[2ex] &\xrightarrow{\text{第2步消元}} \begin{bmatrix} 1 & 0 & \cdots & a_{1n}^{(3)} & b_1^{(3)} \\ 0 & 1 & \cdots & a_{2n}^{(3)} & b_2^{(3)} \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & \cdots & a_{nn}^{(3)} & b_n^{(3)} \end{bmatrix} \\[2ex] &\quad\ \ \vdots \\[2ex] &\xrightarrow{\text{第n步消元}} \begin{bmatrix} 1 & 0 & \cdots & 0 & b_1^{(n+1)} \\ 0 & 1 & \cdots & 0 & b_2^{(n+1)} \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & \cdots & 1 & b_n^{(n+1)} \end{bmatrix} \end{aligned}
第1步消元⎣⎢⎢⎢⎢⎡10⋮0a12(2)a22(2)⋮an2(2)⋯⋯⋱⋯a1n(2)a2n(2)⋮ann(2)b1(2)b2(2)⋮bn(2)⎦⎥⎥⎥⎥⎤第2步消元⎣⎢⎢⎢⎢⎡10⋮001⋮0⋯⋯⋱⋯a1n(3)a2n(3)⋮ann(3)b1(3)b2(3)⋮bn(3)⎦⎥⎥⎥⎥⎤ ⋮第n步消元⎣⎢⎢⎢⎢⎡10⋮001⋮0⋯⋯⋱⋯00⋮1b1(n+1)b2(n+1)⋮bn(n+1)⎦⎥⎥⎥⎥⎤
最终增广矩阵的最后一列即为解:
x
1
=
b
1
(
n
+
1
)
,
x
2
=
b
2
(
n
+
1
)
,
…
,
x
n
=
b
n
(
n
+
1
)
.
x_1 = b_1^{(n+1)}, \quad x_2 = b_2^{(n+1)}, \quad \dots, \quad x_n = b_n^{(n+1)}.
x1=b1(n+1),x2=b2(n+1),…,xn=bn(n+1).
元素更新公式
在第 (k) 步消元中,假设主元已归一化为 1(即
a
k
k
(
k
)
=
1
a_{kk}^{(k)} = 1
akk(k)=1),则对每行
i
≠
k
i \neq k
i=k:
{
a
i
j
(
k
+
1
)
=
a
i
j
(
k
)
−
a
i
k
(
k
)
⋅
a
k
j
(
k
)
,
∀
j
≥
k
,
b
i
(
k
+
1
)
=
b
i
(
k
)
−
a
i
k
(
k
)
⋅
b
k
(
k
)
,
∀
i
≠
k
.
\begin{cases} a_{ij}^{(k+1)} = a_{ij}^{(k)} - a_{ik}^{(k)} \cdot a_{kj}^{(k)}, & \forall j \geq k, \\ b_i^{(k+1)} = b_i^{(k)} - a_{ik}^{(k)} \cdot b_k^{(k)}, & \forall i \neq k. \end{cases}
{aij(k+1)=aij(k)−aik(k)⋅akj(k),bi(k+1)=bi(k)−aik(k)⋅bk(k),∀j≥k,∀i=k.
特点与应用
- 直接求解:最终矩阵为单位矩阵,解直接显式给出,无需回代。
- 计算复杂度:计算量约为 (O(n^3)),略高于普通高斯消元法。
- 应用场景:
- 求矩阵的逆:对单位矩阵进行同步行变换。
- 简化方程组:直接得到最简形式(如线性代数中的行最简形)。
一道实训题
import numpy as np
class GaussianElimination:
def __init__(self, A, b, sol_method="principal"):
self.A = np.asarray(A, dtype=np.float64)
self.b = np.asarray(b, dtype=np.float64)
if len(self.b) != self.A.shape[0]:
raise ValueError("右端向量维度与系数矩阵维度不匹配!")
if self.A.shape[0] != self.A.shape[1]:
raise ValueError("系数矩阵不是方阵,不能用高斯消元法求解!")
self.n = self.A.shape[0]
self.augmented_matrix = np.c_[self.A, self.b]
self.x = None
self.eps = None
self.sol_method = sol_method
self.jordan_inverse_matrix = None
if self.sol_method == "sequential":
self._solve_sequential_()
elif self.sol_method == "column":
self._solve_column_pivot_element_()
elif self.sol_method == "complete":
self._solve_complete_pivot_element_()
elif self.sol_method == "jordan":
self._solve_jordan_()
else:
raise ValueError("仅支持(sequential, column, complete, jordan)")
def _elimination_process(self, i, k):
if self.augmented_matrix[k, k] == 0:
raise ValueError("系数矩阵不满足顺序高斯消元法求解!")
multiplier = self.augmented_matrix[i, k] / self.augmented_matrix[k, k]
self.augmented_matrix[i, k:] -= multiplier * self.augmented_matrix[k, k:]
def _back_substitution_process_(self):
x = np.zeros(self.n)
for k in range(self.n - 1, -1, -1):
sum_ = np.dot(self.augmented_matrix[k, k + 1:self.n], x[k + 1:self.n])
x[k] = (self.augmented_matrix[k, -1] - sum_) / self.augmented_matrix[k, k]
return x
def _solve_sequential_(self):
for k in range(self.n - 1):
for i in range(k + 1, self.n):
self._elimination_process(i, k)
self.x = self._back_substitution_process_()
self.eps = np.dot(self.A, self.x) - self.b
def _solve_column_pivot_element_(self):
for k in range(self.n - 1):
idx = np.argmax(np.abs(self.augmented_matrix[k:, k])) + k
# 修正索引错误,直接用 idx
if idx != k:
self.augmented_matrix[[k, idx]] = self.augmented_matrix[[idx, k]]
for i in range(k + 1, self.n):
self._elimination_process(i, k)
self.x = self._back_substitution_process_()
self.eps = np.dot(self.A, self.x) - self.b
def _solve_complete_pivot_element_(self):
self.x = np.zeros(self.n)
column_index = np.linspace(0, self.n - 1, self.n, dtype=np.int64)
for k in range(self.n - 1):
max_x = np.max(np.abs(self.augmented_matrix[k:, k:k + 1]))
id_r, id_c = np.where(np.abs(self.augmented_matrix[k:, k:k + 1]) == max_x)
id_r, id_c = int(id_r[0]), int(id_c[0])
id_r = id_r + k
if id_r != k:
self.augmented_matrix[[k, id_r]] = self.augmented_matrix[[id_r, k]]
id_c = id_c + k
if id_c != k:
pos = column_index[id_c]
column_index[id_c] = column_index[k]
column_index[k] = pos
self.augmented_matrix[:, [k, id_c]] = self.augmented_matrix[:, [id_c, k]]
for i in range(k + 1, self.n):
self._elimination_process(i, k)
solve_x = self._back_substitution_process_()
for k in range(self.n):
for j in range(self.n):
if k == column_index[j]:
self.x[k] = solve_x[j]
break
self.eps = np.dot(self.A, self.x) - self.b
def _solve_jordan_(self):
self.augmented_matrix = np.c_[self.augmented_matrix, np.eye(self.n)]
for k in range(self.n):
idx = np.argmax(np.abs(self.augmented_matrix[k:, k])) + k
if idx != k:
self.augmented_matrix[[k, idx]] = self.augmented_matrix[[idx, k]]
if self.augmented_matrix[k, k] == 0:
raise ValueError("系数矩阵不满足高斯 - 若尔当消元法")
self.augmented_matrix[k, :] /= self.augmented_matrix[k, k]
for i in range(self.n):
if i != k:
factor = self.augmented_matrix[i, k]
self.augmented_matrix[i, :] -= factor * self.augmented_matrix[k, :]
self.jordan_inverse_matrix = self.augmented_matrix[:, self.n + 1:]
self.x = self.augmented_matrix[:, -self.n - 1]
self.eps = np.dot(self.A, self.x) - self.b
# 给定的线性方程组
A = [
[10, -7, 0, 1],
[-3, 2.099999, 6, 2],
[5, -1, 5, -1],
[2, 1, 0, 2]
]
b = [8, 5.900001, 5, 1]
# 使用列主元高斯消去法求解
solver = GaussianElimination(A, b, sol_method="column")
# 输出结果
print("方程组的解:", solver.x)
print("解的精度验证:", solver.eps)