先貼一段百科ios
數學上,高斯消元法,是線性代數規劃中的一個算法,可用來爲線性方程組求解。但其算法十分複雜,不經常使用於加減消元法,求出矩陣的秩,以及求出可逆方陣的逆矩陣。不過,若是有過百萬條等式時,這個算法會十分省時。一些極大的方程組一般會用迭代法以及花式消元來解決。當用於一個矩陣時,高斯消元法會產生出一個「行梯陣式」。高斯消元法能夠用在電腦中來解決數千條等式及未知數。算法
計算機實現高斯消元法其實利用了矩陣的性質,關於矩陣和行列式的性質見某度百科:spa
行列式 https://baike.baidu.com/item/%E8%A1%8C%E5%88%97%E5%BC%8F code
矩陣 https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5/18069blog
對於方程來講,有:ci
1)兩方程互換,解不變;get
2)一方程乘以非零數k,解不變;數學
3)一方程乘以數k加上另外一方程,解不變it
根據這三項性質, 咱們可將方程中的各個未知數消去, 當方程個數和未知數總數相等時, 咱們能夠經過消元直接得出一個未知數的值, 這個方程必定是可解的.io
對應到行列式, 有行列式的如下性質:
1)對換行列式中兩行的位置,行列式反號
2)行列式的某一行乘任一非零數 k 等於用這個數乘此行列式
3)一行加上另外一行的k倍,行列式的值不變
根據這三條性質, 咱們必定能夠經過一系列流程將行列式轉化成一個上三角, 那麼也就有了在方程中各個未知數的值.
具體的操做流程
1. 用一個非零的數乘矩陣的某一行
2. 將一行的k倍加到另外一行上
3. 交換矩陣中兩行的位置
其餘的代碼裏都寫註釋了
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 5 using namespace std; 6 7 int n; 8 double a[101][102]; 9 10 void solve() 11 { 12 int g; 13 for(int i=1;i<=n;i++)//消元循環,i用於檢索對角線上各個點的行列 14 { 15 if(!a[i][i]) 16 { 17 int r=i; //記錄當前所在的行 18 for(r=i+1;r<=n;r++) //尋找當前列上不爲零的一行 19 if(a[r][i]) 20 { 21 break; 22 } 23 for(int j=1;j<=n+1;j++) 24 swap(a[r][j],a[i][j]); //換行 25 } 26 /* 接下來利用高斯消元法求解 27 實際左下的三角形對整個式子的結果無影響, 28 只需根據它們求上下的比例關係 */ 29 for(int k=i+1;k<=n;k++) //k用於記錄需消元的行 30 for(int j=n+1;j>=i;j--) //j用於記錄該行每一個須要變化的,用於計算結果的係數 31 { 32 a[k][j] -= (a[k][i]/a[i][i])*a[i][j]; 33 } 34 /* 35 這裏是求出了這一行須要消去的係數和它上面對應的數的 36 關係,而後按照這個關係對無需消去的數求差,這裏必定 37 是按照三角形消的,由於最外層循環的i在改變,從而就改 38 變了開始這一「消元」循環的位置,注意用雙精 39 */ 40 } 41 42 for(int i=n;i>=1;i--) //求解循環,從最後一個解倒推 43 { 44 if(!a[i][i]) 45 { 46 cout<<"No Solution"; 47 return; 48 } 49 for(int j=i+1;j<=n;j++) 50 a[i][n+1] -= a[j][n+1]*a[i][j]; //將解存到等式右邊 51 a[i][n+1]/=a[i][i]; //最後的值除以當前的未知數的係數 52 } 53 54 for(g=1;g<=n;g++) 55 printf("%.2lf\n",a[g][n+1]); 56 } 57 58 int main() 59 { 60 int pl; 61 ios::sync_with_stdio(false); 62 cin>>n; 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n+1;j++) 65 cin>>a[i][j]; 66 solve(); 67 68 return 0; 69 }
在這裏感謝Moster_Yi神仙的耐心指導QwQ