高斯消元求线性方程组
高斯消元
给定一个线性方程组,对其求解
何为高斯消元
数学上,高斯消元法(或译:高斯消去法),是线性代数规划中的一个算法,可用来为线性方程组求解。但其算法十分复杂,不常用于加减消元法,求出矩阵的秩,以及求出可逆方阵的逆矩阵。不过,如果有过百万条等式时,这个算法会十分省时。一些极大的方程组通常会用迭代法以及花式消元来解决。当用于一个矩阵时,高斯消元法会产生出一个“行梯阵式”。高斯消元法可以用在电脑中来解决数千条等式及未知数。亦有一些方法特地用来解决一些有特别排列的系数的方程组
高斯消元法思想概念
德国数学家高斯对消元法进行了思考分析,得出了如下结论:
- 在消元法中,参与计算和发生改变的是方程中各变量的系数;
- 各变量并未参与计算,且没有发生改变;
- 可以利用系数的位置表示变量,从而省略变量;
- 在计算中将变量简化省略,方程的解不变。
高斯在这些结论的基础上,提出了高斯消元法,首先将方程的增广矩阵利用行初等变换化为行最简形,然后以线性无关为准则对自由未知量赋值,最后列出表达方程组通解。
我们可以通过高斯消元法可在 复杂度下求出线性方程的解
增广矩阵
所谓增广矩阵,即为方程组系数矩阵 与常数列 的并生成的新矩阵,即 ,增广矩阵行初等变换化为行最简形,即是利用了高斯消元法的思想理念,省略了变量而用变量的系数位置表示变量,增广矩阵中用竖线隔开了系数矩阵和常数列,代表了等于符号
对于
有
增广矩阵
高斯消元的核心步骤
- 把某行乘以一个非0的数
- 交换2行的位置
- 把某行的若干倍加到另一行上
我们把这类操作称为初等行列变化
高斯消元通过一个通用的形式,把我们的方程变为**“阶梯形矩阵”*
阶梯不一定都是这样的,因此我们有
对于
- 完美阶梯型,就会有唯一解
- 不完美阶梯型
3. 若有方程无解
4. 若有方程有无穷多组解
高斯消元算法步骤
- 枚举每一列,找到当前一列,一个绝对值最大的一行
- 将该行换到最上面一行(未确定阶梯型的行,并不是第一行)
- 将该行第一个系数变成1,方程两边同除系数
- 将当前列下面所有行的系数都消为【通过3操作】
- 在枚举继续迭代
代码如下
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int N = 110;
const double esp = 1e-6;
int n;
double a[N][N];
int gauss()
{
int c;//列
int r;//行
for(c = 0,r = 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]) < esp)continue;
/*如果当前这一列绝对值最大为0则
*/
for(int i = c ; i <= n ; i ++ )swap(a[t][i],a[r][i]);//把当前一行换到最上面
for(int i = n ;i >= c ; i--)a[r][i] /=a[r][c];
/*
把当前这一行的第一个数,变成 1, 方程两边同时除以 第一个数,
必须要倒着算,不然第一个数直接变1,系数就被篡改,后面的数字没法算
*/
for(int i = r + 1; i < n ;i ++)
if(fabs(a[i][c]) > esp)//已经是 0就没必要操作了
for(int j = n; j >= c ;j --)// 把当前列下面的所有数,全部消成 0
a[i][j] -= a[r][j] * a[i][c];//把第一行第一个数变成0
r++;//这行工作做完了继续下一行
}
if(r < n)//说明剩下方程的个数是小于 n 的,说明不是唯一解,判断是无解还是无穷多解
{// 因为已经是阶梯型,所以 r ~ n-1 的值应该都为 0
for(int i = r;i < n ; i ++ )
if(fabs(a[i][n]) > esp)
return 2;//无解
return 1;//无限解
}
for(int i = n - 1 ; i >= 0 ; i --)//用最后一列减去除了每一列xi之外的所有其他数
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 ++ )
scanf("%lf",&a[i][j]);
int t = gauss();
if(t == 0 )
{
for(int i = 0; i < n ; i ++ )printf("%.2lf\n",a[i][n]);
}
else if(t == 1)puts("Infinite group solutions");
else puts("No solution");
}
“风雪越是呼啸,雪莲越是绽放”
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!