浅谈高斯消元
浅谈高斯消元
本篇随笔浅谈一下算法竞赛数论内容的高斯消元。
一、高斯消元的概念及应用
高斯消元,顾名思义,是消元用的。什么时候需要用消元呢?在求解线性方程组的时候。所谓线性,也就是一次。
所以高斯消元算法是用来解决线性方程组求解的问题。
二、高斯消元概述
我们先来思考,现在给我们一个线性方程组,我们手算是如何进行求解的?高斯消元算法其实就是在机器模拟这个手算的过程。
我们手算解方程组的步骤大约是:对某个式子两边同时乘除,使得其能够加减消元,然后通过加减消元解出一个未知数,再往其他的式子代入,以此类推的过程。
高斯消元,正是这个原理。
首先,为了让我们能够处理这个方程组,我们把方程组的未知数前系数变成一个矩阵。对于能够出解的方程组,一定是N个式子N元。所以这是一个N行N列的系数矩阵。当然,我们还要把每个式子的答案也放进去(两边同时乘除嘛!),这样的矩阵叫做”增广矩阵“。
比如:
我们希望把这个矩阵处理成这个样子,也就得到了解:
这个矩阵叫做”对角矩阵“。
高斯消元就是把上面的增广矩阵变成下面的对角矩阵。也就得到了解。
其操作有三种,完全够我们处理这个矩阵的问题。
1、交换两行
2、用一个非零实数乘一行
3、把一行加到另一行上
我们把这三类操作叫做矩阵的初等行变换。
通过初等行变换把增广矩阵处理为对角矩阵的过程就是高斯消元。
三、高斯消元的代码实现和细节处理
高斯消元的算法执行思想就是:找到一个当前位是1,其他都是0的方程,然后用初等行变换把其他方程的对应系数都消成0。
它的步骤是:
首先枚举行,然后对于当前行,在剩下的行里寻找当前位置不为0的,swap交换目标行和当前枚举行。
然后从头枚举除房前行外的所有行,计算它需要乘以多少才能和当前行消去,然后对于当前行进行消去。这时需要注意的是,这个行的前i行已经枚举完毕了。所以只需要从i到n枚举即可。
当所有行都遍历完毕之后,高斯消元执行完毕。时间复杂度约为\(O(n^3)\)。所以这只是个可行算法,并不是优化算法。
但是这个算法并不完善,或者说有很多细节需要讨论。
首先,不是所有的方程组都有解。如果出现一个\(0=d\quad(d\neq0)\)的方程,那么就表示方程组无解。
也就是对于矩阵有:
的情况出现。
其次,我们不能保证一定存在一个上述的方程让我们找。
也就是说,可能存在:
的情况出现。这时,这个方程的某一部分是无法确定的。也就是有无穷多个解。
这两个部分要特殊处理无解的情况。
例题: