高斯-约旦消元法 复习笔记

前言#

没有什么意外,发现学过的东西又忘了。
我真的是 AH 第一没脑子选手。

正题#

相对于传统的高斯消元,约旦消元法的精度更好、代码更简单,没有回带的过程。——某洛谷博客

算法流程#

约旦消元法大致思路如下:

  1. 选择一个尚未被选过的未知数作为主元,选择一个包含这个主元的方程。
  2. 将这个方程主元的系数化为1。
  3. 通过加减消元,消掉其它方程中的这个未知数。
  4. 重复以上步骤,直到把每一行都变成只有一项有系数。

算法验证#

先随便列一个方程组:

{3x+y+3z=62x+7y+8z=179x7y+2z=20

高斯-约旦消元 的方法接触当前方程的解。

  • 先把方程组转化成为矩阵的形式。
    以上文的方程组为例,我们列出这样的一个矩阵:

[31362781797220]

  • 看第一列,从上到下扫描,发现绝对值更大的就直接交换。

[31362781797220][97220278173136]

  • 然后运用消元的办法消元就可以了捏。(太懒了不想再算这种申必的系数)
  • 之后的直接重复上面的两步就可以了。

最后会变成一个类似这样的东西:

[a1,100a0a2,20b01a3,3c]

直接算就好了。

注意:当出现有一列全部为零时,说明无解。

Code#

#include <bits/stdc++.h>

#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)

#define Enter putchar('\n')
#define quad putchar(' ')

#define N 1005

int n;
double a[N][N];

signed main(void) {
  // file("P3389");
  std::cin >> n;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n + 1; j++)
      scanf("%lf", &a[i][j]);
  
  for (int i = 1; i <= n; i++) {
    int maxn = i;
    for (int j = i + 1; j <= n; j++)
      if (fabs(a[j][i]) > fabs(a[maxn][i])) maxn = j;
    for (int j = 1; j <= n + 1; j++)
      std::swap(a[i][j], a[maxn][j]);
    if (!a[i][i]) {printf("No Solution\n"); return 0;}
    for (int j = 1; j <= n; j++) {
      if (j == i) continue;
      double tmp = a[j][i] / a[i][i];
      for(int k= i + 1; k <= n + 1; k++)
        a[j][k] -= a[i][k] * tmp;
    }
  }

  for (int i = 1; i <= n; i++)
    printf("%.2lf\n", a[i][n + 1] / a[i][i]);
}

作者:Aonynation

出处:https://www.cnblogs.com/Oier-GGG/p/16155981.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Aonynation  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示