高斯消元解线性方程组
文章目录
- 基础知识
- 算法步骤
- 举个例子模拟一下算法
- 例题和代码
基础知识
高斯消元可以通过初等行列变化把 增广矩阵 转换成 阶梯型矩阵,进而求解 n 个线性方程组的解,其时间复杂为 O(n^3)
初等行列变换:(对一个方程组进行以下三个操作不会影响方程的解)
- 把某一行乘一个非0的数(方程左右两边同乘)
- 交换某两行的位置
- 把某一行的若干倍加到另一行上
例如线性方程组为:
a11x1 + a12x2 + a13x3 + … + a1nxn = b1
a21x1 + a22x2 + a23x3 + … + a2nxn = b2
…
an1x1 + an2x2 + an3x3 + … + annxn = bn
则增广矩阵为:
a11 a12 a13 ... a1n b1
a21 a22 a23 ... a2n b2. ..
a21 a22 an3 ... ann bn
经过三种初等行列变换,上面的增广矩阵就可以形成一个阶梯型矩阵:
a11 a12 a13 ... a1n b1a22 a23 ... a2n b2. ..ann bn
算法步骤
枚举每一列 c:
① 找到列 c 绝对值最大的一行
② 将该行换到最上面
③ 将该行第一个数变成 1 (即第 c 列的数变成 1)
④ 将下面所有行第 c 列消成 0
每枚举一列,都能将一行换到最上面(绝对值最大为 0 除外),换到最上面说明当前这行已经固定了,所以,下次枚举某一列时,将绝对值最大的那一行换到最上面时(即②步骤),并不是换到第一行,而是换到没有固定的行的最上面,同样,步骤①也是在未固定的行中找绝对值最大的。
答案有三种解:
如果经过以上步骤得到的是一个完美阶梯型矩阵(即得到 n 个唯一方程,即每个方程不会被另一个方程表示出来),说明有唯一解。
如果转换后出现 0==0 的方程,说明这个方程可以被其他方程表示出来,说明有 多组解。(n元方程组要想有唯一解,需要有n个唯一的方程)
如果转换后出现 0==非0 的方程,说明无解。
举个例子模拟一下算法
若方程组为:
x1 + 2x2 - x3 = -6
2x1 + x2 - 3x3 = -9
-x1 - x2 + 2x3 = 7
则增广矩阵为:
1 2 -1 -6
2 1 -3 -9
-1 -1 2 7
枚举第 1 列:
① 找到第 1 列绝对值最大的一行
② 将该行换到最上面
③ 将该行第一个数变成 1(即第 1 列)
注:橙色字体为已经固定的行
④ 将下面所有行第 1 列消成 0
枚举第 2 列:
① 找到第 2 列绝对值最大的一行
② 将该行换到最上面
该行其实已经在未固定行中的最上面了
③ 将该行第一个数变成 1(即第 2 列)
④ 将下面所有行第 c 列消成 0
枚举第 3 列:
① 找到第 3 列绝对值最大的一行
② 将该行换到最上面
该行其实已经在未固定行中的最上面了
③ 将该行第一个数变成 1 (即第 c 列的数变成 1)
④ 将下面所有行第 c 列消成 0
这一行已经是最后一行了,没有下面的行了
枚举完所有列后,我们发现这个矩阵是完美阶梯矩阵,说明是有唯一解的
确定有唯一解后,从最后一行开始向上回代,第三行直接可求出 x3 = 3,然后将 x3 回代到第二行,求出 x2 = -2,再将 x1、x2 回代到第一行,求出 x1 = 1。
综上
x1 = 1
x2 = -2
x3 = 3
例题和代码
AcWing 883. 高斯消元解线性方程组
#include<iostream>
#include<cmath>
using namespace std;
const int N = 105;
const double eps = 1e-6; //如果 x < eps,就说明 x 是等于0的
int n;
double a[N][N];int gauss()
{int c, r; // c 是列数、r 是行数for(c = 0, r = 0; c < n; c++) //枚举每一列 {int t = r;for(int i=r; i<n; i++) // 找到第 c 列的值最大的是哪一行 if(fabs(a[i][c]) > fabs(a[t][c]))t = i;if(fabs(a[t][c]) < eps) continue; //当前这一列最大值都为 0,说明这一列所有系数都为0for(int i=c; i<=n; i++) swap(a[t][i],a[r][i]); //把绝对值最大的这行(即第t行)换到当前最上面去(第r行)for(int i=n; i>=c; i--) a[r][i] /= a[r][c]; //把第t行第一个数变成1(方程所有数同除第一个数即可)//要先处理最后一个数,因为如果先处理第一个数,第一个数先变为1了,后面所有数就会都除1而不是第一个数for(int i =r+1; i<n; i++) //枚举从 r+1 的每一行,把第 c 列的数全部消成 0 if(fabs(a[i][c]) > eps) //如果已经 ==0 ,就不用消了for(int j=n; j>=c; j--) //枚举这一行的每个数 a[i][j] -= a[r][j] * a[i][c]; //每个数减去a[i][c] * a[r][j] 即可 r++; //该下一行了 }if(r < n) //说明剩下的方程数小于 n 个,需要判断是 无解 还是 有多组解 { //现在已经是阶梯型,所有系数都应该为0,如果等式右边a[i][n] != 0,说明无解 for(int i=r; i<n; i++)if(fabs(a[i][n]) > eps)return 2; //无解return 1; //多组解,说明 r~n-1的这些方程是可以被 0~n 的某些方程表示出来的}//有唯一解,从下向上回代,依次求解 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()
{cin >> 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++) printf("%.2lf\n",a[i][n]);} else if(t == 1) printf("Infinite group solutions\n"); //有多组解else printf("No solution\n"); //无解
}
高斯消元解线性方程组相关推荐
- 第三十四章 数论——高斯消元解线性方程组
第三十四章 数论--高斯消元解线性方程组 一.高斯消元 1.线性方程组 2.高斯消元步骤 (1)数学知识铺垫 增广矩阵和阶梯矩阵 初等变换 (2)高斯消元步骤 二.代码模板 1.问题: 2.代码 一. ...
- [AcWing]883. 高斯消元解线性方程组(C++实现)高斯消元解线性方程组模板题
[AcWing]883. 高斯消元解线性方程组(C++实现)高斯消元解线性方程组模板题 1. 题目 2. 读题(需要重点注意的东西) 3. 解法 4. 可能有帮助的前置习题 5. 所用到的数据结构与算 ...
- 高斯消元 AcWing 883. 高斯消元解线性方程组
高斯消元 AcWing 883. 高斯消元解线性方程组 原题链接 AcWing 883. 高斯消元解线性方程组 算法标签 线性代数 高斯消元 思路 代码 #include<bits/stdc++ ...
- 高斯消元——解线性方程组+球形空间产生器+开关问题
传送门:https://www.acwing.com/activity/content/11/ 思路: 把原矩阵变成阶梯型矩阵解题步骤: 1.找到绝对值最大的一行. 2.将该行和最上面未处理好的一行交 ...
- AcWing 883. 高斯消元解线性方程组(高斯消元模板)
先出裸的模板: #include<bits/stdc++.h>using namespace std; const int N = 110; typedef double db; db a ...
- AcWing 883. 高斯消元解线性方程组 (高斯消元)
题目链接 : 点击查看 题目描述 : 输入一个包含 n 个方程 n 个未知数的线性方程组. 方程组中的系数为实数. 求解这个方程组. 下图为一个包含 m 个方程 n 个未知数的线性方程组示例: 输入输 ...
- 高斯消元解线性方程组(浮点高斯消元模板)
题目连接 https://www.acwing.com/problem/content/885/ 思路 高斯消元的思路如下: 1.我们从上到下,从左到右开始消元,对于每一行我们只保留当前[i,i]行的 ...
- AcWing - 高斯消元解线性方程组(高斯消元)
题目链接:https://www.acwing.com/problem/content/885/ 时/空限制:1s / 64MB 题目描述 输入一个包含n个方程n个未知数的线性方程组. 方程组中的系数 ...
- 【BZOJ1923】外星千足虫,高斯消元解xor方程组
Time:2016.08.29 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 原本以为是高斯消元解取模方程,后来发现这题意不就和异或方程一样吗 [异或(XOR)运算由于与" ...
- HDU 4305 Lightning (高斯消元解kirchhoff矩阵+逆元)
题意是:给一些坐标点,如果两点之间的距离小于R,并且两点之间没有其他点,则这两个点保持连通,这样构成了一个图.问这个图中生成树的个数. 因为数据量并不大,O(N^3)的建图没有问题. 建好图以后就可以 ...
最新文章
- Python 标准库之 subprocesss
- p ython笔记第一天
- 操作系统(九)进程控制
- Scala if...else案例
- Redis内部数据结构-跳跃表
- HTML+CSS+JS实现 ❤️swiper倾斜图片特效❤️
- 教你React Native使用fetch实现图片上传
- 今年暑假不ac (c语言版)
- iphone6出信号 无服务器,苹果6手机无服务(非常见故障点)维修
- 处理Simulink的代数环的方法为逐个添加一阶惯性环节
- 博帝 boost和威刚S102哪个好详细原创评测
- 【技术综述】一文道尽传统图像降噪方法
- 免费的中文深度学习全书:《深度学习理论与实战:提高篇》
- [转载] 网页制作常用英语标示
- 【爬坑记录】记录搭建fabric 遇到的问题-network e2ecli_default not found
- java中隐函数求导法则_隐函数求导法则
- 热释电人体感应红外报警器设计 - 没人取消报警
- 解决echart在tab中切换时显示不正确
- 常见状态码(200、403、404、500)
- 地铁牵引供电系统MATLAB/Simulink仿真建模