欢迎光临
我们一直在努力

打开——高斯消元

1. 引言

高斯消元法(Gaussian Elimination)是线性代数中最基础、最重要的算法之一,用于求解线性方程组、计算矩阵的秩、求逆矩阵以及计算行列式等。该方法由德国数学家卡尔·弗里德里希·高斯在 19 世纪初系统化,但类似的思想早在古代中国《九章算术》中就已出现。

高斯消元法的核心思想是通过一系列初等行变换,将系数矩阵化为行阶梯形(Row Echelon Form)或简化行阶梯形(Reduced Row Echelon Form),从而简化方程组的求解过程。

2. 算法原理

2.1 线性方程组表示

一个包含 n 个未知数、m 个方程的线性方程组可以表示为:

a₁₁x₁ + a₁₂x₂ + … + a₁ₙxₙ = b₁
a₂₁x₁ + a₂₂x₂ + … + a₂ₙxₙ = b₂

aₘ₁x₁ + aₘ₂x₂ + … + aₘₙxₙ = bₘ

用矩阵形式表示为:Ax = b,其中:

  • A 是 m×n 的系数矩阵;
  • x 是 n×1 的未知数向量;
  • b 是 m×1 的常数向量。

2.2 增广矩阵

为了方便计算,我们将系数矩阵 A 和常数向量 b 合并为增广矩阵(augmented matrix):

[A | b] =
[ a₁₁ a₁₂ … a₁ₙ | b₁ ]
[ a₂₁ a₂₂ … a₂ₙ | b₂ ]
[ … … … … | … ]
[ aₘ₁ aₘ₂ … aₘₙ | bₘ ]

2.3 初等行变换

高斯消元法允许的三种初等行变换为:

  • 交换两行(Row Swapping):交换矩阵中的任意两行。
  • 行倍乘(Row Multiplication):将某一行乘以一个非零常数。
  • 行倍加(Row Addition):将某一行乘以常数后加到另一行上。
  • 这些变换不会改变线性方程组的解集。

    3. 算法步骤

    3.1 前向消元(Forward Elimination)

    目标:将增广矩阵化为行阶梯形(Row Echelon Form, REF)

    行阶梯形的特征:

  • 所有非零行都在全零行的上方
  • 每行的主元(第一个非零元素)所在列严格递增
  • 主元下方的元素全为零
  • 算法步骤:

  • 从第一行开始,找到当前列中绝对值最大的元素作为主元(选主元法,提高数值稳定性)
  • 如果需要,交换当前行与主元所在行
  • 将主元所在行除以主元值,使主元变为 1(可选步骤,简化计算)
  • 用当前行消去下方所有行的当前列元素
  • 移动到下一行下一列,重复上述过程
  • 3.2 回代求解(Back Substitution)

    目标:将行阶梯形化为简化行阶梯形(RREF)并求解。

    简化行阶梯形的特征:

  • 满足行阶梯形的所有条件。
  • 每个主元都是 1。
  • 主元所在列的其他元素全为 0。
  • 算法步骤:

  • 从最后一行开始,该行通常只有一个未知数,可直接求解。
  • 将已求得的未知数代入上一行方程。
  • 依次向上回代,求解所有未知数。
  • 4. 代码实现

    4.1 Python 实现

    import numpy as np

    def gaussian_elimination(A, b):
    """
    高斯消元法求解线性方程组 Ax = b

    参数:
    A: n×n 系数矩阵
    b: n×1 常数向量

    返回:
    x: 解向量
    """
    n = len(A)

    # 构造增广矩阵
    Ab = np.hstack([A, b.reshape(1, 1)])

    # 前向消元
    for i in range(n):
    # 选主元(部分选主元法)
    max_row = i + np.argmax(np.abs(Ab[i:, i]))
    if max_row != i:
    Ab[[i, max_row]] = Ab[[max_row, i]]

    # 如果主元为 0,方程组无解或有无穷多解
    if np.abs(Ab[i, i]) < 1e-10:
    raise ValueError("矩阵奇异或接近奇异,无法求解")

    # 消去下方行的当前列元素
    for j in range(i + 1, n):
    factor = Ab[j, i] / Ab[i, i]
    Ab[j, i:] -= factor * Ab[i, i:]

    # 回代求解
    x = np.zeros(n)
    for i in range(n 1, 1, 1):
    x[i] = (Ab[i, 1] np.dot(Ab[i, i+1:n], x[i+1:])) / Ab[i, i]

    return x

    # 示例
    A = np.array([[2, 1, 1],
    [3, 1, 2],
    [2, 1, 2]], dtype=float)
    b = np.array([8, 11, 3], dtype=float)

    x = gaussian_elimination(A, b)
    print("解向量 x =", x)
    print("验证 Ax – b =", np.dot(A, x) b)

    4.2 C++ 实现

    #include <iostream>
    #include <vector>
    #include <cmath>
    #include <algorithm>

    using namespace std;

    vector<double> gaussianElimination(vector<vector<double>> A, vector<double> b) {
    int n = A.size();

    // 构造增广矩阵
    vector<vector<double>> Ab(n, vector<double>(n + 1));
    for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
    Ab[i][j] = A[i][j];
    }
    Ab[i][n] = b[i];
    }

    // 前向消元
    for (int i = 0; i < n; i++) {
    // 选主元
    int maxRow = i;
    double maxVal = fabs(Ab[i][i]);
    for (int k = i + 1; k < n; k++) {
    if (fabs(Ab[k][i]) > maxVal) {
    maxVal = fabs(Ab[k][i]);
    maxRow = k;
    }
    }

    // 交换行
    if (maxRow != i) {
    swap(Ab[i], Ab[maxRow]);
    }

    // 检查主元是否为0
    if (fabs(Ab[i][i]) < 1e-10) {
    throw runtime_error("矩阵奇异,无法求解");
    }

    // 消去下方行的当前列元素
    for (int k = i + 1; k < n; k++) {
    double factor = Ab[k][i] / Ab[i][i];
    for (int j = i; j <= n; j++) {
    Ab[k][j] -= factor * Ab[i][j];
    }
    }
    }

    // 回代求解
    vector<double> x(n);
    for (int i = n 1; i >= 0; i) {
    double sum = 0.0;
    for (int j = i + 1; j < n; j++) {
    sum += Ab[i][j] * x[j];
    }
    x[i] = (Ab[i][n] sum) / Ab[i][i];
    }

    return x;
    }

    int main() {
    vector<vector<double>> A = {{2, 1, 1},
    {3, 1, 2},
    {2, 1, 2}};
    vector<double> b = {8, 11, 3};

    vector<double> x = gaussianElimination(A, b);

    cout << "解向量 x = [";
    for (int i = 0; i < x.size(); i++) {
    cout << x[i];
    if (i < x.size() 1) cout << ", ";
    }
    cout << "]" << endl;

    return 0;
    }

    5. 算法复杂度分析

    5.1 时间复杂度

    对于 n×n 的矩阵:

    • 前向消元:约需要 2n³/3 次浮点运算。
    • 回代求解:约需要 n² 次浮点运算。
    • 总复杂度:O(n³)。

    对于 m×n 的矩阵(m ≥ n):

    • 总复杂度为 O(mn²)

    5.2 空间复杂度

    • 原地算法:O(1) 额外空间(直接在原矩阵上操作)
    • 非原地算法:O(mn) 额外空间
    赞(0)
    未经允许不得转载:171主机测评 » 打开——高斯消元
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址