高斯消元学习笔记
Posted XINNNNNNNYU
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯消元学习笔记相关的知识,希望对你有一定的参考价值。
高斯消元
默认大家都学过线代了
算法思想:
-
就是求解矩阵的过程。把矩阵转化成一个上三角或者下三角的形式,那么只需要把对角线上的元素相乘就可以 O ( n ) O(n) O(n) 得到矩阵的值。
-
如何把矩阵转化成上三角或下三角呢,线性代数告诉我们把第i行的每个元素加上第j行对应的每个元素的k倍,原矩阵大小不变。(同理可以消除列)
-
判断解的情况:
a) 如果出现某一行,系数矩阵全为0,增广矩阵不全为0,则无解(即出现[0 0 0 0 0 b],其中b不等于0的情况)(转化为方程就是说 0 × x 1 + . . . + 0 × x n = b ( b ≠ 0 ) 0 \\times x_1 + ...+0 \\times x_n = b(b \\neq 0) 0×x1+...+0×xn=b(b=0) ,显然这不可能);
b) 如果是严格上三角,则表明有唯一解;
形如下图,以对角线为线,左下角全为0或右上角
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cb2IwFV9-1670482002823)(https://tse1-mm.cn.bing.net/th/id/R-C.d85ea5d58289c8b027ec7dd7dbb8ec26?rik=CmoIe2fedyOvCQ&riu=http%3a%2f%2fc.biancheng.net%2fuploads%2fallimg%2f190426%2f1KJR1D-5.gif&ehk=VYbXtHCtR86m65HblKk1JWB5G5OO%2bnEn8uOO1nsW7AM%3d&risl=&pid=ImgRaw&r=0&sres=1&sresct=1)]
c) 如果增广矩阵有k (k > 0)行全为0(全为0指b也等于0),那么表明有k个变量可以任 意取值,这几个变量即自由变量;对于这种情况,一般解的范围是给定的,令解的取值 有T个,自由变量有V个,那么解的个数就是 TV。
ACWING的基础模板题(防止没买基础课的看不了,题目也加上了)
-
-
题目:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SI14vpel-1670482002824)(https://s6.jpg.cm/2021/11/15/Iit3LE.png)]
-
代码+板子
#include <iostream> #include <algorithm> #include <cmath> using namespace std; const int N = 110; const double eps = 1e-6; int n; double a[N][N]; int gauss() int c, 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]) < eps) continue; for (int i = c; i < n + 1; i ++ ) swap(a[t][i], a[r][i]); for (int i = n; i >= c; i -- ) a[r][i] /= a[r][c]; for (int i = r + 1; i < n; i ++ ) if (fabs(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 (fabs(a[i][n]) > eps) return 2; return 1; for (int i = n - 1; i >= 0; i -- ) for (int j = i + 1; j < n; j ++ ) a[i][n] -= a[j][n] * a[i][j]; 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) puts("Infinite group solutions"); else puts("No solution"); return 0;
-
-
-
题目:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tYEKWrkQ-1670482002824)(https://s6.jpg.cm/2021/11/15/IitCbQ.png)]
-
板子+代码
#include <iostream> #include <algorithm> using namespace std; const int N = 110; int n; int a[N][N]; int gauss() int c, r; for (c = 0, r = 0; c < n; c ++ ) int t = r; for (int i = r; i < n; i ++ ) if (a[i][c]) t = i; if (!a[t][c]) continue; for (int i = c; i <= n; i ++ ) swap(a[r][i], a[t][i]); for (int i = r + 1; i < n; i ++ ) if (a[i][c]) for (int j = n; j >= c; j -- ) a[i][j] ^= a[r][j]; r ++ ; if (r < n) for (int i = r; i < n; i ++ ) if (a[i][n]) return 2; 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; 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 ++ ) cout << a[i][n] << endl; else if (t == 1) puts("Multiple sets of solutions"); else puts("No solution"); return 0;
-
题型分类
-
浮点数消元
系数矩阵为整数或浮点数,消元的时候乘上的系数为浮点数,一般用于求解浮点数解
-
整数消元
系数矩阵全为整数,消元的时候乘上的系数均为整数,整个消元过程不出现浮点数。由于乘法很容易溢出,一般很少用。(真迫不得已就上Java,Python)
-
模线性方程组(很有用)
系数矩阵全为整数,消元的时候乘上的系数均为整数,每次运算都模上一个数P,整个消元过程不出现除法。(因为高斯消元的过程和最后的计算都是只有±×,对取模后的结果都没影响,这样算出来的结果和原来答案取模后是一样的)
- 有的是给定解的范围求解的数量,例如:PKU 1830、HDU 3364
- 有的是求一个解,例如PKU 2065、HDU 3571
- 有的是求解的存在性,例如PKU1288、PKU 3185。
- 有的是已知解得绝对值求正负,例如2021icpc济南J
以上是关于高斯消元学习笔记的主要内容,如果未能解决你的问题,请参考以下文章