高斯消元解线性方程组

基础知识

求方程组的解即为线性代数中Ax=b的解。
通过高斯消元,将每一个要解的变量系数化为1。
若主对角线上均为1,则正好有一组解,带回求解即可。
若有一组方程化简完后为 0=0形式,则有无数组解。
若有一组方程为,0 = b的形式,那么则无解。
代码即为模拟消元的过程:
模板题:https://www.acwing.com/problem/content/885/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include<bits/stdc++.h>
using namespace std;
const int N =110;
double a[N][N];
const double eps = 1e-8;//浮点数精度问题
int n;
int gauss()
{
int c;
int r =0;
for(c=0;c<n;c++)//遍历每一列
{
int t =r;
for(int i=r;i<n;i++)
{
if(fabs(a[i][c])>fabs(a[t][c])) t =i;//找到绝对值最大值
}
if(fabs(a[t][c])<eps) continue;//如果最大值为0,那么所有数都为0.
for(int i =c;i<=n;i++) swap(a[t][i],a[r][i]);//将该行换到第r行
for(int i=n;i>=c;i--) a[r][i] = a[r][i]/a[r][c];//当前行第一个非0数变为1,同时对该行所有系数除
for(int i=r+1;i<n;i++)// 把当前列下面的所有数,全部消成 0
{
if(abs(a[i][c])>eps)//当该列的数不为0时
{
for(int j=n;j>=c;j--)
{
a[i][j] =a[i][j] -a[r][j]*a[i][c];//第r行的所有系数乘以a[i][c]倍
//从而把当前列下面的所有数都消成0
//因为第r行第c列的系数已经为1.
}
}
}
r++;//处理下一行
}
if(r<n)//剩下方程的个数是小于 n 的,说明不是唯一解,判断是无解还是无穷多解
{
// 因为已经是阶梯型,所以 r ~ n-1 的值应该都为 0
for (int i = r; i < n; i ++ )//
if (fabs(a[i][n]) > eps)// a[i][n] 代表 b_i ,即 左边=0,右边=b_i,0 != b_i, 所以无解。
return 2;
return 1;// 否则, 0 = 0,就是r ~ n-1的方程都是多余方程,有无穷组解。
}
//有唯一解,从下往上带,得到方程的解
for(int i=n-1;i>=0;i--)//行
{
for(int j=i+1;j<n;j++)
{
a[i][n] =a[i][n]- a[j][n] * a[i][j];
//因为只要得到解,所以只用对 b_i 进行操作,中间的值,可以不用操作,因为不用输出
}
}
return 0;
}
int main(void)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
for(int j=0;j<=n;j++)
{
scanf("%lf",&a[i][j]);
}
}
int res= gauss();
if(res==1)
{
printf("Infinite group solutions\n");
}
else if(res==2)
{
printf("No solution\n");
}
else
{
for(int i=0;i<n;i++)
{
if (fabs(a[i][n]) < eps) a[i][n] = 0;
printf("%.2lf\n",a[i][n]);
}
}


}

高斯消元解线性方程组
http://jty-123.github.io/2022/04/19/高斯消元解线性方程组/
作者
Jty
发布于
2022年4月19日
许可协议