当前位置: 首页 > news >正文

解线性方程组的直接方法:高斯消元法与其程序实现

解线性方程组的直接方法:高斯消元法与其程序实现

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] a11a21an1a12a22an2a1na2nannx1x2xn=b1b2bn高斯消元法a11(1)00a12(1)a22(2)0a1n(1)a2n(2)ann(n)x1x2xn=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)=kinmaxaik(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) (nk+1)×(nk+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)=kin,kjnmaxaij(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=n1,,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 步)

  1. 选取主元:在第 k k k列中选取绝对值最大的元素作为主元(部分选主元法)。
  2. 归一化主元行:将主元所在行除以主元值,使主元位置为 1 1 1
  3. 消去主元列的所有非主元元素
    • 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步消元 100a12(2)a22(2)an2(2)a1n(2)a2n(2)ann(2)b1(2)b2(2)bn(2)2步消元 100010a1n(3)a2n(3)ann(3)b1(3)b2(3)bn(3)  n步消元 100010001b1(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),jk,i=k.


特点与应用
  1. 直接求解:最终矩阵为单位矩阵,解直接显式给出,无需回代。
  2. 计算复杂度:计算量约为 (O(n^3)),略高于普通高斯消元法。
  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)
    

相关文章:

  • 如何通过 iTick 外汇数据 API 与 Cursor AI 实现量化策略开发
  • 设计模式的六大原则
  • PHP回调后门分析
  • 比R版本快几十倍| Pyscenic单细胞转录因子预测
  • 项目日记 -云备份 -服务端配置信息模块
  • 深入解析 Python 正则表达式:全面指南与实战示例
  • Python实现小红书app版爬虫
  • CSS圣杯布局与双飞翼布局
  • WordPress超级菜单插件UberMenu v3.78汉化版
  • NVIDIA TensorRT-LLM:高性能大语言模型推理框架详解
  • AI与.NET技术实操系列(一):开篇
  • CentOS 7 更换 yum 源(阿里云)+ 扩展 epel 源
  • vue3,element-plus 表格单选、多选、反选、全选
  • [深度学习]图像分类项目-食物分类
  • QuecPython 网络协议之TCP/UDP协议最祥解析
  • 实战经验:Gone 框架模块化改造中的 go work 反思
  • 10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?
  • 信奥赛CSP-J复赛集训(模拟算法专题)(31):P2692 覆盖
  • 部署Jenkins
  • 提升通信清晰度:通过PoE交换机端口配置语音VLAN
  • 朝鲜新型驱逐舰“崔贤”号进行多项武器试验
  • 五大国有银行明确将撤销监事会
  • 阿里开源首个“混合推理模型”:集成“快思考”、“慢思考”能力
  • 伊朗港口爆炸已致46人死亡
  • 牛市早报|今年国内核电项目审批首次开闸,离境退税起退点下调
  • 十四届全国人大常委会第十五次会议在京举行,审议民营经济促进法草案等