高斯-约旦消元法

Posted qimang-311

tags:

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

一般的高斯消元需要回代,所以就显得比较赘余,一般选用高斯-约旦消元法

首先给定一个多元一次方程组

技术图片

我们可以直接写A出它的增广矩阵直接求出他的解

同理对于方矩阵A技术图片

我们可以利用初等变化求出它的逆矩阵

证明如下:

对于矩阵(A,B)进行初等变化变为(E,P)易知p就是A的逆矩阵

关于高斯-约旦消元法就是利用此种方法求解

技术图片

接下来进行初等变化

分为步

1.找出第I列的主元(元素值最大的那个)然后交换到第I行(已经交换到前面的就无需考虑)

2.求出对角线也就是第(i,i)个元素的逆元(由于需要mod,所以该逆元可以理解为他的倒数

3.直接更改当前行乘以逆元,你会发现第(i,i)个元素直接就是1

4.所以随后只要减去1*该列除了主元以外其他元素的值,依次消元

如下图所示1.

2. 技术图片

3. 技术图片

4. 技术图片

技术图片

代码如下

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
const int maxn=300;
const int mod=998244353;
ll a[maxn][maxn<<1];
ll quickpow(ll a,ll b,ll p)
{
    ll  ans=1;
    while (b)
    {
      if (b&1)///b为奇数
        ans=(ans*a)%p;
       a=(a*a)%p;///b为偶数
       b>>=1;
    }
    return ans;
}
for(re int i=1,t;i<=n;++i)
        {
          t=i;
          for(re int j=i+1;j<=n;++j)///找出每一列的最大主元
          {
            if(abs(a[j][i])>abs(a[t][i]))///找寻最大主元
            {
                t=j;
            }
          }
          if(i^t)///相当于i!=t,保证不在当前行
          {
            swap(a[i],a[t]);///交换行
          }
          ll w=quickpow(a[i][i],mod-2,mod);///直接求出对角元素值,方便消元

          for(re int j=1;j<=n;++j)
          {
            if(j!=i)///当前行直接乘以逆元即可,无需进行消元
            {
                ll tmp=a[j][i]*w%mod;///主元乘以逆元
                for(int k=i;k<=(n<<1);++k)
                {
                    a[j][k]=((a[j][k]-a[i][k]*tmp)%mod+mod)%mod;///该点元素直接减去i行元素乘以对称点(i i)的逆元
                }

            }
          }
          for(re int j=1;j<=(n<<1);++j)a[i][j]=(w*a[i][j])%mod;///最后当前行直接乘以逆元保证主元为1,最后能得到单位矩阵
        }

以上是关于高斯-约旦消元法的主要内容,如果未能解决你的问题,请参考以下文章

高斯消元——约旦消元法

高斯-约旦消元法

模板高斯(约旦)消元

模板 - 高斯约旦消元法

高斯约旦消元法

高斯消元总结