首页 > 其他分享 >【数学】高斯消元

【数学】高斯消元

时间:2024-07-18 08:59:23浏览次数:10  
标签:frac cdot cdots 数学 bmatrix 高斯消 vdots

1. 算法简介

高斯消元法(Gauss–Jordan elimination)是求解线性方程组的经典算法。

例如求解下列方程组:

\( \begin{cases}2x+9y-5z=10\\ 4x+20y+z=24\\ x-2y+3z=8 \end{cases} \)

形式化的,高斯消元可用于求解类似于

\( \begin{cases} a_{1,1} x_1+a_{1,2} x_2+\dots+a_{1,n} x_n = b_1\\ a_{2,1} x_1+a_{2,2} x_2+\dots+a_{2,n} x_n = b_2\\ \dots\\ a_{n,1} x_1+a_{n,2} x_2+\dots+a_{n,n} x_n = b_n\\ \end{cases} \)

的方程组。

2. 算法理论

2.1 高斯消元

先将线性方程组转化为矩阵:

\( \begin{bmatrix} a_{1,1}&a_{1,2}&\cdots&a_{1,n}&b_1\\ a_{2,1}&a_{2,2}&\cdots&a_{2,n}&b_2\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ a_{n,1}&a_{n,2}&\cdots&a_{n,n}&b_n\\ \end{bmatrix} \)

显然为一个 \(n\times (n+1)\) 的矩阵。

我们希望将它消成上三角的形式,如下:

\( \begin{bmatrix} w_{1,1}&w_{1,2}&\cdots&w_{1,n}&B_1\\ 0&w_{2,2}&\cdots&w_{2,n}&B_2\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ 0&0&\cdots&a_{n,n}&B_n\\ \end{bmatrix} \)

我们可以枚举对角线,依次将对角线下面的所有数消成 \(0\)。

例如第一次操作利用 \(a_{1,1}\) 将 \(a_{2,1},a_{3,1}\dots a_{n,1}\) 消成 \(0\)。

\( \begin{bmatrix} a_{1,1}&a_{1,2}&\cdots&a_{1,n}&b_1\\ a_{2,1} - \frac{a_{2,1}}{a_{1,1}}\cdot a_{1,1}&a_{2,2} - \frac{a_{2,1}}{a_{1,1}}\cdot a_{1,1}&\cdots&a_{2,n} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&b_2 - \frac{a_{2,1}}{a_{1,1}}\cdot a_{1,1}\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ a_{n,1} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&a_{n,2} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&\cdots&a_{n,n} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&b_n - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}\\ \end{bmatrix} \)

变成:

\( \begin{bmatrix} a_{1,1}&a_{1,2}&\cdots&a_{1,n}&b_1\\ 0&a_{2,2} - \frac{a_{2,1}}{a_{1,1}}\cdot a_{1,1}&\cdots&a_{2,n} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&b_2 - \frac{a_{2,1}}{a_{1,1}}\cdot a_{1,1}\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ 0&a_{n,2} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&\cdots&a_{n,n} - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}&b_n - \frac{a_{n,1}}{a_{1,1}}\cdot a_{1,1}\\ \end{bmatrix} \)

依次类推消掉下三角的所有数,消成上三角的形式:

\( \begin{bmatrix} w_{1,1}&w_{1,2}&\cdots&w_{1,n}&B_1\\ 0&w_{2,2}&\cdots&w_{2,n}&B_2\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ 0&0&\cdots&a_{n,n}&B_n\\ \end{bmatrix} \)

然后回带,依次相减。消成对角线的形式:

\( \begin{bmatrix} W_{1,1}&0&\cdots&0&C_1\\ 0&W_{2,2}&\cdots&0&C_2\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ 0&0&\cdots&W_{n,n}&C_n\\ \end{bmatrix} \)

则答案 \(x_i=\frac{B_i}{W_{i,i}}\).

判断解的情况:

  1. 若 \(\exists i\) 使得 \(W_{i,i}=0\) 且 \(C_i \not= 0\),则方程组无解;
  2. 若 \(\exists i\) 使得 \(W_{i,i}=0\) 且 \(C_i = 0\),则方程组有无数解;

误差处理:

  1. 由于误差传递,要将 \(a_{i,i}=0\) 写成 \(fabs(a_{i,i})<0\);
  2. 为了减小误差,每次将小的数除以大的数再去消元;

2.1 高斯-约旦消元

对于矩阵

\( \begin{bmatrix} a_{1,1}&a_{1,2}&\cdots&a_{1,n}&b_1\\ a_{2,1}&a_{2,2}&\cdots&a_{2,n}&b_2\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ a_{n,1}&a_{n,2}&\cdots&a_{n,n}&b_n\\ \end{bmatrix} \)

枚举对角线 \((i,i)\),找到 \(a_{i,i}\not=0\) 的一行,交换至第一行,依次消元;

高斯消元为每一次往下消元,而高斯-约旦消元为每一次将除本行的其他行全部消元。

由于每一次都会将除对角线外的所有数消成 \(0\),所以高斯-约旦消元后只剩下了

\( \begin{bmatrix} W_{1,1}&0&\cdots&0&C_1\\ 0&W_{2,2}&\cdots&0&C_2\\ \vdots&\vdots&\ddots&\vdots&\vdots\\ 0&0&\cdots&W_{n,n}&C_n\\ \end{bmatrix} \)

不需要高斯消元的回带过程。

3. 算法实现

luoguP3389 【模板】高斯消元法

高斯消元模板

#include<bits/stdc++.h>
#define int long long
#define For(i,l,r) for(int i=l;i<=r;++i)
#define FOR(i,r,l) for(int i=r;i>=l;--i)
#define eqs 1e-7

using namespace std;

const int N = 1e3 + 10;

int n;

double a[N][N];

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n;
  For(i,1,n) {
    For(j,1,n+1) {
      cin >> a[i][j];
    }
  }
  for (int i = 1; i <= n - 1; ++i) {
    For(j,i+1,n) if(fabs(a[i][i]) < fabs(a[j][i])) swap(a[i], a[j]);
    if(fabs(a[i][i]) < eqs) continue;
    For(j,i+1,n) {
      double w = a[j][i] / a[i][i];
      For(l,i,n+1) {
        a[j][l] -= w * a[i][l];
      }
    }
  }
  for (int i = n; i >= 2; --i) {
    if(fabs(a[i][i]) < eqs) continue;
    FOR(j,i-1,1) {
      double w = a[j][i] / a[i][i];
      For(l,i,n+1) {
        a[j][l] -= w * a[i][l];
      }
    }
  }
  For(i,1,n) {
    int cnt0 = 0;
    For(j,1,n) {
      cnt0 += (a[i][j] == 0);
    }
    if(cnt0 == n) return puts("No Solution"), 0;
  }
  For(k,1,n) {
    printf("%.2lf\n", a[k][n+1] / a[k][k]);
  }
  return 0;
}

/*
9 3       2         2 
0 3.66667 6.77778   2.77778 
0 0       -1.15152  2.75758 


9 0       2         -13.5526 
0 3.66667 0         19.0088 
0 0       -1.15152  2.75758
 */

luoguP2455 [SDOI2006] 线性方程组

高斯-约旦模板。

高斯消元的华点在于这样一组样例:

4
0 0 1 1 2
0 0 1 0 1
0 0 0 1 1
0 0 0 0 0
0

直接用高斯消元模板会出现对角线全 \(0\) 而无法消元的情况。

#include<bits/stdc++.h>
#define ll long long
#define For(i,l,r) for(int i=l;i<=r;++i)
#define FOR(i,r,l) for(int i=r;i>=l;--i)
#define eps 1e-9

using namespace std;

const int N = 55;

int n;

double a[N][N];

bool st[N];

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n;
  For(i,1,n) {
    For(j,1,n+1) {
      cin >> a[i][j];
    }
  }
  For(i,1,n) {
    For(j,1,n) if(fabs(a[i][i]) < fabs(a[j][i]) && !st[j]) swap(a[i], a[j]), swap(st[i], st[j]);
    if(fabs(a[i][i]) < eps) continue;
    st[i] = 1;
    For(j,1,n) {
      if(i == j) continue;
      double w = a[j][i] / a[i][i];
      For(l,1,n+1) {
        a[j][l] -= w * a[i][l];
      }
    }
  }
  For(i,1,n) if(fabs(a[i][i]) < eps && fabs(a[i][n+1]) > eps) return puts("-1"), 0; 
  For(i,1,n) if(fabs(a[i][i]) < eps && fabs(a[i][n+1]) < eps) return puts("0"), 0;
  For(k,1,n) {
    printf("x%d=%.2lf\n", k, a[k][n+1] / a[k][k]);
  }
  return 0;
}

标签:frac,cdot,cdots,数学,bmatrix,高斯消,vdots
From: https://www.cnblogs.com/Daniel-yao/p/18308249

相关文章

  • 逆天的数学 | 数学科普
    前言所有自然数的和相加为多少呢,即\(1\)\(+\)\(2\)\(+\)\(3\)\(+\)\(4\)\(+\)\(5\)\(+\)\(6\)\(+\)\(\cdots\)\(=\)\(?\),估计我们都会说是\(+\infty\),但数学家说\(1\)\(+\)\(2\)\(+\)\(3\)\(+\)\(4\)\(+\)\(5\)\(+\)\(6\)\(+\)\(\cdots......
  • 组合数学
    $\large1.$容斥原理\[f(n)=\sum_{i=0}^n\dbinom{n}{i}g(i)\Leftrightarrowg(n)=\sum_{i=0}^n(-1)^{n-i}\dbinom{n}{i}f(i)\]$\largef$表示至多,\(\largeg\)表示恰好\[f(n)=\sum_{i=n}^m\dbinom{i}{n}g(i)\Leftrightarrowg(n)=\sum_{i......
  • G68 实数线性基+高斯消元法 P3265 [JLOI2015] 装备购买
    视频链接:G68实数线性基+高斯消元法P3265[JLOI2015]装备购买_哔哩哔哩_bilibili  P3265[JLOI2015]装备购买-洛谷|计算机科学教育新生态(luogu.com.cn)//线性基+高斯消元法O(n*m*m)#include<iostream>#include<cstring>#include<algorithm>usingnames......
  • 新时代多目标优化【数学建模】领域的极致探索——数学规划模型
    目录例11.问题重述 2.基本模型  变量定义:目标函数:约束条件: 3.模型分析与假设 4.模型求解 5.LINGO代码实现 6.结果解释 ​编辑 7.敏感性分析 8.结果解释例2奶制品的销售计划1.问题重述 ​编辑 2.基本模型3.模型求解 4.结果解释 3.整数规划的实......
  • 【密码学】密码学数学基础:剩余系
        不得不啃的密码学数学基础之剩余系是个啥?数学里面有好多的定义都有前置的数学概念,要想弄懂剩余系还得先说说“同余”。一、同余    那么“同余”有是个什么呢?在谈论“同余”之前,我们先圈定个讨论的范围。接下来讨论的都是整数集合。好了!可以正式开始介绍......
  • opencv—常用函数学习_“干货“_7
    目录十九、模板匹配从图像中提取矩形区域的子像素精度补偿(getRectSubPix)在图像中搜索和匹配模板(matchTemplate)比较两个形状(轮廓)的相似度(matchShapes)解释二十、图像矩计算图像或轮廓的矩(moments)计算图像或轮廓的Hu不变矩(HuMoments)解释使用示例二一、......
  • P9963前缀和_数学推导解法
    P9963前缀和数学推导解法\(\operatorname{E}{\sum\limits_{i=1}^n[l\ley_i\ler]}\\=\sum\limits_{i=1}^n\operatorname{E}[l\ley_i\ler]\\=\sum\limits_{i=1}^n\operatorname{E}[l\le\sum\limits_{j=1}^ix_j\ler]\\=\sum\limits_{i=1}^n\operatorna......
  • 具体数学
    Part1递归式1.1汉诺塔问题设\(T_n\)是将\(n\)个圆盘从一个柱桩移动到另一根柱桩所需要的最少移动步数。不难得到\(T_n=2T_n+1\)。为了将求\(T_n\)从\(O(n)\)转化到\(O(1)\),需要将递推式转化为封闭形式。找规律不难发现\(T_n=2^n-1\),考虑严谨的证明。数......
  • 2024辽宁省数学建模C题【改性生物碳对水中洛克沙胂和砷离子的吸附】原创论文分享
    大家好呀,从发布赛题一直到现在,总算完成了2024年辽宁省大学数学建模竞赛C题改性生物碳对水中洛克沙胂和砷离子的吸附完整的成品论文。本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。C题论文共47页,一些修改......
  • 2024辽宁省数学建模B题【钢铁产品质量优化】原创论文分享
    大家好呀,从发布赛题一直到现在,总算完成了2024年辽宁省大学数学建模竞赛B题钢铁产品质量优化完整的成品论文。本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。B题论文共47页,一些修改说明9页,正文33页,附录5页......