高斯消元解线性方程组
2025-11-21 22:12:03
发布于:广东
5阅读
0回复
0点赞
注:图片来源于网络
对于n个未知数n个方程构成的线性方程

我们对线性方程组可以做如下三种变换:

算法步骤:

我们对线性方程组做变换的目的是为了将其化为与之同解的如下形式的线性方程组

最后求解

#include<bits/stdc++.h>
using namespace std;
double a[110][110];
int n;
//先在每一列中找到绝对值最大的元素所在的行 与当前行进行交换 避免除数为0 因为后面会用到除法
//从第一行开始 将第i列的第i+1行到最后一行 消元变为0
//回代
int gauss(){
int r = 0;//r表示当前在处理第几行
for(int c = 0; c < n; c++){//遍历每一列
int t = r; //t记录绝对值最大的这一行
for (int i = r; i < n; i ++ ){ // 第一步,找绝对值最大的行
if(abs(a[i][c]) > abs(a[t][c]))
t = i;
}
if(abs(a[t][c]) < 1e-8 ) continue; // 因为记录的是绝对值最大的,如果绝对值最大还是0,那么代表这一列已经被处理过了
for(int i = 0; i <= n; i++) // 第二步
swap(a[t][i], a[r][i]); // 将这一行调到第r行
for(int i = n; i >= c; i--) // 第三步 小于c的不用考虑 因为已经处理为0了
a[r][i] /= a[r][c]; // 要倒着算,否则会影响后面的数
//如果从前往后遍历会导致a[r][c]变成1 导致答案错误
for(int i = r + 1; i < n; i++) {// 第四步 遍历后面每一行 把当前这个数字改为0
if(abs(a[i][c]) > 1e-8){ // 如果是0就不用操作了
for(int j = n; j >= c; j--){//这一排都要进行更改
a[i][j] -= a[r][j] * a[i][c];
}
}
}
r++;//下一行
}
if(r < n) {// 如果最后几行没有进行消元 会出现一些只有纯数字的方程 比如1=0 0=0
for(int i = r; i < n; i++){
if(abs(a[i][n]) > 1e-8){ // 0 != 0
return 2; // 无解
}
}
return 1; // 无数解, 0=0
}
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;
}
int main(){
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n + 1; j ++ )
cin>>a[i][j];
int t = gauss();
if(t == 0) { // 有唯一解
for (int i = 0; i < n; i ++ ){
if(abs(a[i][n]) < 1e-8) a[i][n] = 0.00; // 精度问题 小于这个范围的统一写成0
cout<<"x"<<i+1<<"=";
printf("%.2lf\n", a[i][n]);
}
}
else if(t == 1) printf("0"); // 无数解
else printf("-1"); // 无解
}
这里空空如也

有帮助,赞一个