高斯消元学习笔记

Posted XINNNNNNNYU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯消元学习笔记相关的知识,希望对你有一定的参考价值。

高斯消元

默认大家都学过线代了

算法思想

  1. 就是求解矩阵的过程。把矩阵转化成一个上三角或者下三角的形式,那么只需要把对角线上的元素相乘就可以 O ( n ) O(n) O(n) 得到矩阵的值。

  2. 如何把矩阵转化成上三角或下三角呢,线性代数告诉我们把第i行的每个元素加上第j行对应的每个元素的k倍,原矩阵大小不变。(同理可以消除列)

  3. 判断解的情况:

    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的基础模板题(防止没买基础课的看不了,题目也加上了)

  • 883. 高斯消元解线性方程组 - 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;
      
      
      
      
  • 884. 高斯消元解异或线性方程组 - AcWing题库

    • 题目:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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

以上是关于高斯消元学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

高斯消元学习笔记

高斯消元学习笔记

高斯消元

高斯消元+叉积求面积+记忆化搜索

高斯消元总结

P3389 模板高斯消元法