高斯消元


解線性方程組

高斯消元

我們想想人類是如何解線性方程組的,一個例子

\[\begin{cases} x+y+z=1\cdots(1)\\ x+2y+3z=2\cdots(2)\\ x+2y+2z=3\cdots(3) \end{cases} \]

運用小學數學知識,(2)-(3)就可以解出\(\,z\,\),(1)-(3)就可以解出\(\,y+z\,\),依次帶回即可解出所以未知數

考慮模擬此過程,我們先將方程組抽象為矩陣,每一位表示方程中一個未知數在某個方程中的系數(我們認為常數項也是一個\(x^0\)的系數)

那么我們只需要使得這個矩陣滿足\(\forall i>j , a_{i,j}=0\),即上三角形式

考慮矩陣基本變換:

1.交換行或列

2.行列帶系數作差

於是我們只需要每次選定一個元,將矩陣中在它下方同一行系數全部變為0即可

考慮邊界情況

一行全為0,無數解

一行常數項不為0,其他全為0,無解

讀者自證不難

高斯約旦消元

考慮高斯消元回帶不好寫,精度也不高,我們消元時直接消成對角形式,就是每行每列都只有一個值不為0

Talk is cheap , show you the code

read_(n);
for(int i(1);i<=n;++i)
    for(int j(1);j<=n+1;++j)
        cin>>(x[i][j]);
int pl;
double c;
for(int i(pl=1);i<=n;pl=++i)
{
    while(x[pl][i]==0.0&&pl<=n) ++pl;
    if(pl==n+1) cout<<"No Solution",exit(0);
    if(pl!=i) for(int j(i);j<=n+1;++j) swap(x[i][j],x[pl][j]);
    c=x[i][i];
    for(int j(i);j<=n+1;++j) x[i][j]/=c;
    for(int j(i+1);j<=n;++j)
        if(x[j][i]!=0.0)
            for(int k(n+1);k>=i;--k)
                x[j][k]-=x[j][i]*x[i][k];
}
for(int i(n);i>1;--i)
    for(int j(i-1);j;--j)
        if(x[j][i]!=0.0)
            x[j][n+1]-=x[i][n+1]*x[j][i],x[j][i]=0.0;
for(int i(1);i<=n;++i)
    printf("%.2f\n",x[i][n+1]);

復雜度\(\,\Theta(n^3)\,\),看代碼容易發現


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM