Loading

浅谈高斯-约旦消元法

适用场景

高斯-约旦消元用于解线性方程组,其参考了数学中解方程组的过程。

具体过程

顺次枚举 \(x_1\sim x_n\) 作为主元。对于未知数 \(x_i\),将当前系数最大的方程移到第 \(i\) 的位置,然后将 \(n\) 个方程(除了第 \(i\) 个方程)的 \(x_i\) 的系数都变为 \(0\),这个过程可以通过加减消元来解决。注意我们只用每个方程中 \(x_i\sim x_n\) 的系数,因为 \(x_1\sim x_{i-1}\) 的系数已经被处理完了。最后方程组会形成形如 \(k_ix_i=v_i,1\le i\le n\)。对于每个 \(x_i\) 求出其解即可。

如果最后存在某一行系数都为 \(0\),就说明并不是唯一解。根据 \(v_i\) 是否为 \(0\) 判断是无解还是无穷解。

代码

#include<cmath>
#include<cstdio>
#include<algorithm>
#define N 105
#define db double
using namespace std;
int n;
db a[N][N];
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;
        for (int j=1;j<=n+1;++j)
            swap(a[i][j],a[mx][j]);
        if (!a[i][i]) 
        {
            printf("No Solution\n");
            return 0;
        }
        for (int j=1;j<=n;++j)
            if (i!=j)
            {
                db t=a[j][i]/a[i][i];
                for (int k=i;k<=n+1;++k)
                    a[j][k]-=a[i][k]*t;
            }
    }
    for (int i=1;i<=n;++i)
        printf("%.2lf\n",a[i][n+1]/a[i][i]);
    return 0;
}
posted @ 2023-11-10 16:14  Thunder_S  阅读(73)  评论(0编辑  收藏  举报