• 高斯-约旦消元方法(预览)


    前言
    本文并不打算讨论任何关于高斯-约旦消元算法某一步的正确性以及为什么要那样做, 仅给出算法流程以及示例代码(Luogu高斯消元模板题)。
    本文的判无唯一解方法可能是不完美的, 也绝对是不精细(无法区分无解和无穷多解)的。


    高斯-约旦消元的作用:
    同高斯消元。

    解形如

    [egin{cases} a_{11}x_1 + a_{12}x_2 + dots + a_{1n}x_n = b_1\ a_{21}x_1 + a_{22}x_2 + dots + a_{2n}x_n = b_2\ vdots qquad qquad qquad ddots qquadqquad qquad vdots \ a_{n1}x_1 + a_{n2}x_2 + dots + a_{nn}x_n = b_n\ end{cases} ]

    的线性方程组


    一点扯淡
    对于线性方程组有三种 “初等行变换”, 分别是

    • 交换两行
    • 将某行减去某行
    • 将某行乘一个非零数

    这三种 “初等行变换” 的共同特点是 不改变方程组的本质

    高斯-约旦消元 和 高斯消元 通过这三种 “初等行变换” 来解线性方程组。


    消元过程与无唯一解的情况

    过程:
    (n) 步, 第 (i) 步选出 未被选过的行中 (x_i) 的系数最大的那一行, 运用初等行变换, 将其他所有行的 (x_i) 的系数变为 (0)

    (n) 步结束后, 可以直接得到方程组的解。

    无唯一解的情况
    若在某一步 (i) 中选出的 未被选过的行中 (x_i) 的系数最大的那一行的 (x_i) 的系数为 (0), 则无唯一解。


    代码实现
    这里选用的例题是Luogu的高斯消元模板题。

    #include<bits/stdc++.h>
    using namespace std;
    #define db double
    const int maxn = 135;
    const db eps = 1e-13;
    
    int n;
    db a[maxn][maxn];
    
    void fail() {
    	cout << "No Solution";
    }
    int main()
    {
    	scanf("%d", &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 mx=i; for(int j=i+1;j<=n;++j)if(fabs(a[j][i])>fabs(a[mx][i])) mx=j;// 注意一定是绝对值最大, 具体可以思考+实践试错qwq 
    		swap(a[i], a[mx]);// 似乎是通过交换指针实现交换行, 不过管他呢, 反正怎么交换复杂度都没有影响 
    		if(fabs(a[i][i]) < eps) {fail(); return 0;}
    		for(int j=1;j<=n;++j) if(j^i) { // ((a^b)==1) == ((a!=b)==1)
    			// 将其他行消元 
    			register db tmp = a[j][i]/a[i][i];
    			for(int k=i;k<=n+1;++k) a[j][k] -= a[i][k]*tmp;
    		}
    	}
    	for(int i=1; i<=n; ++i) printf("%.2lf
    ", a[i][n+1]/a[i][i]);
    	return 0;
    }
    
  • 相关阅读:
    正则表达式30分钟入门教程
    oracle常用的字符和字符串处理类函数
    [转载]C#实现软件自动更新思路
    ORACLE函数介绍
    xml 文件操作类
    oracle 主键生成策略
    wmsys.wm_concat、sys_connect_by_path、自定义函数实现行列转换
    NSIS开始...
    Oracle分析函数详述
    常用正则表达式收集
  • 原文地址:https://www.cnblogs.com/tztqwq/p/12777974.html
Copyright © 2020-2023  润新知