高斯消元Gauss
引入
-
高斯消元法(Gauss-Jordan elimination)是求解線性方程組的經典算法,它在當代數學中有着重要的地位和價值,是線性代數課程教學的重要組成部分。
-
高斯消元法除了用於線性方程組求解外,還可以用於行列式計算、求矩陣的逆,以及其他計算機和工程方面。
-
夏建明等人之前提出了應用圖形處理器 (GPU) 加速求解線性方程組的高斯消元法,所提出的算法與基於 CPU 的算法相比較取得更快的運算速度。二是提出各種變異高斯消元法以滿足特定工作的需要。
今天主要討論最基礎的高斯消元
原理
相信大家在初中的時候就會用消元法解二元一次方程了
消元法理論的核心主要如下:
-
兩方程互換,解不變;
-
一方程乘以非零數 ,解不變;
-
一方程乘以數 加上另一方程,解不變。
德國數學家高斯在長期的研究中得出了以下結論
-
在消元法中,參與計算和發生改變的是方程中各變量的系數;
-
各變量並未參與計算,且沒有發生改變;
-
可以利用系數的位置表示變量,從而省略變量;
-
在計算中將變量簡化省略,方程的解不變。
於是乎 就出現了高斯消元
-
將方程的增廣矩陣通過行初等變換為成為行最簡行
-
還原線性方程組
-
求解第一個變量
-
帶入求值 求出剩余未知量
-
列方程組求通解
增廣矩陣就差不多是……
\[\left[ \begin{array}{ccc|c} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \end{array} \right] \]
分割線左邊的就是方程每項的系數 右邊就是方程右邊的常數
實踐
貼上例題代碼
class Martix {
private :
int n ;
double ans[N] ;
double martix[N][N] ;
bool is_zero(double x) {
return fabs(x) < eps ;
}
public :
Martix(int x){
memset(martix,x,sizeof martix) ;
}
void Init(Martix* &Rt) {
Rt -> n = read() ;
for (int i = 1 ; i <= Rt -> n ; ++i )
for (int j = 1 ; j <= Rt -> n + 1 ; ++j )
scanf("%lf",&Rt -> martix[i][j]) ;
}
void solve(Martix* &Rt) {
for (int i = 1 ; i <= Rt -> n ; ++i ) {
int mx = i ;
for (int j = i + 1 ; j <= Rt -> n ; ++j )
if (fabs(Rt -> martix[mx][i]) < fabs(Rt -> martix[j][i]))
mx = j ;
if (is_zero(Rt -> martix[mx][i])) {
puts("No Solution") ;
exit(0) ;
}
if (i != mx) swap(Rt -> martix[i],Rt -> martix[mx]) ;
double div = Rt -> martix[i][i] ;
for (int j = i ; j <= Rt -> n + 1 ; ++j )
Rt -> martix[i][j] /= div ;
for (int j = i + 1 ; j <= Rt -> n ; ++j ) {
div = Rt -> martix[j][i] ;
for (int k = i ; k <= Rt -> n + 1 ; ++k )
Rt -> martix[j][k] -= Rt -> martix[i][k] * div ;
}
} return void() ;
}
void calc(Martix* &Rt) {
Rt -> ans[Rt -> n] = Rt -> martix[Rt -> n][Rt -> n + 1] ;
for (int i = Rt -> n - 1 ; i ; --i ) {
Rt -> ans[i] = Rt -> martix[i][Rt -> n + 1] ;
for (int j = i + 1 ; j <= Rt -> n ; ++ j )
Rt -> ans[i] -= Rt -> martix[i][j] * Rt -> ans[j] ;
}
return void() ;
}
void write(Martix* &Rt) {
for (int i = 1 ; i <= Rt -> n ; ++i )
printf("%.2lf\n",ans[i]) ;
return void() ;
}
} ;