日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高斯消元法讲解

發(fā)布時間:2025/3/20 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高斯消元法讲解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


高斯消元的本質(zhì)就是化簡成一個階梯式的行列式。
首先線性方程組的解有以下三種情況:

  • 無解
  • 有無窮多個解
  • 有唯一解

高斯消元的步驟分為以下四步:

  • 枚舉每一行找到當前行(包括當前行)下面的,當前列的絕對值最大的一個數(shù)。
  • 將其絕對值最大的一行移到上面
  • 將改行的第一個數(shù)變成1
  • 將下面所有的行的當前列都清成0

例子:

注意:這里剛開始是第一行和第一列,以此類推就會化簡成一個階梯行列式。

https://www.acwing.com/problem/content/description/885/
按照上面的步驟模擬的代碼如下:

#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> using namespace std; const int N=110; const double eps=1e-6; double a[N][N]; int n; void print() {for(int i=1;i<=n;i++){for(int j=1;j<=n+1;j++)cout<<a[i][j]<<" ";cout<<endl;}cout<<endl; } int gauss() {int c,r;for(c=1,r=1;c<=n;c++){int t=r;for(int i=r;i<=n;i++)//1 尋找 {if(fabs(a[i][c])>fabs(a[t][c])) t=i;}if(fabs(a[t][c])<eps) continue;for(int i=c;i<=n+1;i++) swap(a[r][i],a[t][i]);//2 交換for(int i=n+1;i>=c;i--) a[r][i]=a[r][i]/a[r][c];//3 化簡 for(int i=r+1;i<=n;i++)//將該行下面的該列都清零{if (fabs(a[i][c]) > eps)//如果當前列不為0,為0的話就不用清了了。for(int j=n+1;j>=c;j--){a[i][j]-=a[i][c]*a[r][j];}} r++;}if (r <= n)//說明我們的 第r到 第n行都是全零。{for (int i = r; i <= n; i ++ )//如果常數(shù)項不為零就會產(chǎn)生 0 = 3 這種矛盾if (fabs(a[i][n+1]) > eps)return 2;//無解return 1;}for (int i = n; i >=1; i -- )//倒著推解for (int j = i + 1; j <= n; j ++ )a[i][n+1] -= a[j][n+1] * a[i][j];return 0; } int main(void) {cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n+1;j++)cin>>a[i][j];}int t=gauss();if (t == 0){for (int i = 1; i <= n; i ++ ) printf("%.2lf\n", a[i][n+1]);}else if (t == 1) puts("Infinite group solutions");else puts("No solution");return 0; }

下面開始回答一些常見的不懂的問題:

問題一:為啥化簡為 1的操作,和清零的操作都要倒著推。


當然你也可以正著推,不過你要用一個變量來記錄一下開頭的元素的值。化簡都除以這個值就行了。
不過著稍微有點麻煩。
那么此時的代碼就如下所示:

#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> using namespace std; const int N=110; const double eps=1e-6; double a[N][N]; int n; void print() {for(int i=1;i<=n;i++){for(int j=1;j<=n+1;j++)cout<<a[i][j]<<" ";cout<<endl;}cout<<endl; } int gauss() {int c,r;for(c=1,r=1;c<=n;c++){int t=r;for(int i=r;i<=n;i++)//1 尋找 {if(fabs(a[i][c])>fabs(a[t][c])) t=i;}if(fabs(a[t][c])<eps) continue;for(int i=c;i<=n+1;i++) swap(a[r][i],a[t][i]);//2 交換double x=a[r][c];for(int i=c;i<=n+1;i++) a[r][i]=a[r][i]/x;//3 化簡 for(int i=r+1;i<=n;i++){if (fabs(a[i][c]) > eps){double x=a[i][c];for(int j=c;j<=n+1;j++){a[i][j]-=x*a[r][j];}}} r++;}if (r <= n){for (int i = r; i <= n; i ++ )if (fabs(a[i][n+1]) > eps)return 2;return 1;}for(int i=n;i>=1;i--)for(int j=i+1;j<=n;j++)a[i][n+1]-=a[j][n+1]*a[i][j];return 0; } int main(void) {cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n+1;j++)cin>>a[i][j];}int t=gauss();if (t == 0){for (int i = 1; i <= n; i ++ ) printf("%.2lf\n", a[i][n+1]);}else if (t == 1) puts("Infinite group solutions");else puts("No solution");return 0; }

問題二:if (fabs(a[t][c]) < eps) continue;如何理解。

假設 c表示列,r表示行,此時我們進行到了 c=2 r=2
1 0 2 3
0 0 3 2
0 0 2 3
你會發(fā)現(xiàn)此時r行之下 的c列的絕對值最大值就是0.
說明此時的第c列已經(jīng)化簡好了那么,那么我們就不需要在進行下面的化簡操作,
但是此時我們的第r行不用變,此時c加1 那么我們就接著從 第二行 第三列開始找絕對值最大的數(shù)。
如果我們的r向后移動了,那么此時我們的第2行是沒有化簡的,這顯然是不對的。
以此為例,r如果向后移動了,此時r=3,c=3 但是此時我們的 第二行 第三個數(shù) 是 3 并不是1 這種最簡的形態(tài)。

問題三:倒著推解是如何來的

當有唯一解的時候,我們最后的化簡一定是這種。
解的最終形式,如下所示:

我們倒著將每一行都簡成每一行只有一個1 的形式。 這里模擬一下,代碼就懂了。這里不在贅述。

最后,謝謝各位的觀看。我們下期再見!!!

總結

以上是生活随笔為你收集整理的高斯消元法讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。