高斯消元


高斯消元Gauss

引入

  • 高斯消元法(Gauss-Jordan elimination)是求解線性方程組的經典算法,它在當代數學中有着重要的地位和價值,是線性代數課程教學的重要組成部分。

  • 高斯消元法除了用於線性方程組求解外,還可以用於行列式計算、求矩陣的逆,以及其他計算機和工程方面。

  • 夏建明等人之前提出了應用圖形處理器 (GPU) 加速求解線性方程組的高斯消元法,所提出的算法與基於 CPU 的算法相比較取得更快的運算速度。二是提出各種變異高斯消元法以滿足特定工作的需要。

今天主要討論最基礎的高斯消元


原理

相信大家在初中的時候就會用消元法解二元一次方程了

消元法理論的核心主要如下:

  1. 兩方程互換,解不變;

  2. 一方程乘以非零數 ,解不變;

  3. 一方程乘以數 加上另一方程,解不變。

德國數學家高斯在長期的研究中得出了以下結論

  1. 在消元法中,參與計算和發生改變的是方程中各變量的系數;

  2. 各變量並未參與計算,且沒有發生改變;

  3. 可以利用系數的位置表示變量,從而省略變量;

  4. 在計算中將變量簡化省略,方程的解不變。

於是乎 就出現了高斯消元

  • 將方程的增廣矩陣通過行初等變換為成為行最簡行

  • 還原線性方程組

  • 求解第一個變量

  • 帶入求值 求出剩余未知量

  • 列方程組求通解

增廣矩陣就差不多是……

\[\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() ;
        }
} ;


免責聲明!

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



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