mobile wallpaper 1
mobile wallpaper 2
mobile wallpaper 3
mobile wallpaper 4
550 字
2 分钟
高斯消元
2026-03-31

高斯消元#

概念详解#

解决的问题: 解 n 元一次线性方程组:

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

把系数和常数项拼成一个 n × (n+1) 的增广矩阵,通过三种行变换(交换两行、某行乘非零常数、某行的倍数加到另一行)把矩阵化成”阶梯形/行最简形”,就能直接读出解。

算法步骤(列主元高斯消元):

  1. 选主元: 对当前列 c,从第 r 行往下找绝对值最大的那一行(避免除 0 和精度损失),换到第 r 行;
  2. 归一: 把该行除以主元,使主元位置变成 1;
  3. 消元: 用该行把下面所有行的第 c 列消成 0;
  4. 处理下一列、下一行,直到所有列处理完;
  5. 回代: 从最后一行往上,把每个未知数代入已求出的结果,解出所有变量。

解的情况判断: 设处理后非零行的个数为 r(秩):

  • r = n: 有唯一解(回代求出);
  • r < n 且某行出现 0 = 非零(即系数全 0 但常数项不为 0):无解
  • r < n 且没有矛盾行: 无穷多解(有 n - r 个自由变量)。

精度处理: 浮点比较一律用 eps(如 1e-6):Math.abs(x) < eps 视为 0;输出时把 -0.00 归零。时间复杂度 O(n³)。

例题#

题意#

输入一个包含 nn 个方程 nn 个未知数的线性方程组,系数与常数为实数。 求解这个方程组:唯一解则输出每个未知数(保留两位小数);无解输出 No solution;无穷多解输出 Infinite group solutions

输入格式#

第一行一个整数 nn
接下来 nn 行,每行 n+1n+1 个实数,表示一个方程的 nn 个系数与常数项。

输出格式#

唯一解:共 nn 行,第 ii 行输出 xix_i(保留两位小数);
无穷多解:输出 Infinite group solutions
无解:输出 No solution

数据范围#

1n100,aij,bi1041 \leq n \leq 100,\quad |a_{ij}|, |b_i| \leq 10^4

import java.io.*;
import java.util.StringTokenizer;
public class Main {
static final int N = 110;
static final double EPS = 1e-6;
static double[][] a = new double[N][N];
static int n;
// 返回值:0 唯一解,1 无穷多解,2 无解
static int gauss() {
int c = 0, r = 0;
for (; c < n; c++) {
// 1. 找当前列绝对值最大的行(选主元)
int t = r;
for (int i = r; i < n; i++)
if (Math.abs(a[i][c]) > Math.abs(a[t][c])) t = i;
if (Math.abs(a[t][c]) < EPS) continue; // 该列全 0,跳过
// 2. 把主元行交换到第 r 行
double[] tmp = a[t]; a[t] = a[r]; a[r] = tmp;
// 3. 主元归一
for (int j = n; j >= c; j--) a[r][j] /= a[r][c];
// 4. 用第 r 行消去下面所有行的第 c 列
for (int i = r + 1; i < n; i++)
if (Math.abs(a[i][c]) > EPS)
for (int j = n; j >= c; j--)
a[i][j] -= a[r][j] * a[i][c];
r++;
}
if (r < n) { // 存在自由变量
for (int i = r; i < n; i++)
if (Math.abs(a[i][n]) > EPS) return 2; // 0 = 非零 → 无解
return 1; // 无穷多解
}
// 回代:自底向上解出每个未知数
for (int i = n - 1; i >= 0; i--)
for (int j = i + 1; j < n; j++)
a[i][n] -= a[i][j] * a[j][n];
return 0;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine().trim());
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j <= n; j++) a[i][j] = Double.parseDouble(st.nextToken());
}
int t = gauss();
if (t == 0) {
for (int i = 0; i < n; i++)
System.out.printf("%.2f\n", Math.abs(a[i][n]) < EPS ? 0.0 : a[i][n]);
} else if (t == 1) {
System.out.println("Infinite group solutions");
} else {
System.out.println("No solution");
}
}
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

高斯消元
https://blogstella.xyz/posts/数据结构之高斯消元/
作者
Stella
发布于
2026-03-31
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录