高斯消元

高斯消元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() ;
        }
} ;
posted @ 2021-08-21 07:50  xxcxu  阅读(409)  评论(0编辑  收藏  举报