数学/数论专题-学习笔记:线性方程组解法(高斯消元/高斯-约旦消元)
1. 前言
高斯消元/高斯-约旦消元法,常常在 O ( n 3 ) O(n^3) O(n3) 的复杂度内用于解线性方程组问题。
前置知识:解多元方程组的解法——加减消元,带入消元。
别信洛谷上面的官方模板题,那道题没这道题模板。
2. 高斯消元法
以下讨论的所有方程组均默认只有唯一解。
首先我们回顾一下正常的方程组解法:
例子:解方程组:
{ 2 x + 3 y = 8 ( 1 ) 3 x + 4 y = 11 ( 2 ) \begin{cases}2x+3y=8&(1)\\3x+4y=11&(2)\end{cases} {2x+3y=83x+4y=11(1)(2)
解: ( 2 ) × 2 − ( 1 ) × 3 (2) \times 2-(1) \times 3 (2)×2−(1)×3,得方程 − y = − 2 -y=-2 −y=−2,解得 y = 2 y=2 y=2。
带回 ( 1 ) (1) (1),得 2 x + 6 = 8 2x+6=8 2x+6=8,解得 x = 1 x=1 x=1。
所以原方程组的解是 { x = 1 y = 2 \begin{cases}x=1\\y=2\end{cases} {x=1y=2。
显然上述过程利用了加减消元法则以及我们的智慧解出了这个方程组正确的解。
但是很遗憾的是我们的计算机没有我们的智慧,我们需要制定一个法则来消元。
初中老师和高中老师应该都强调过,解方程组很重要的一步是消元,高斯正是基于消元提出了高斯消元法。
那么看一下一般的高斯消元法的步骤:
解 n n n 元线性方程组:
{ a 1 , 1 x 1 + a 1 , 2 x 2 + ⋯ + a 1 , n x n = a 1 , n + 1 a 2 , 1 x 1 + a 2 , 2 x 2 + ⋯ + a 2 , n x n = a 2 , n + 1 … a n , 1 x 1 + a n , 2 x 2 + ⋯ + a n , n x n = a n , n + 1 \begin{cases}a_{1,1}x_1+a_{1,2}x_2+\dots+a_{1,n}x_n=a_{1,n+1}\\a_{2,1}x_1+a_{2,2}x_2+\dots+a_{2,n}x_n=a_{2,n+1}\\\dots\\a_{n,1}x_1+a_{n,2}x_2+\dots+a_{n,n}x_n=a_{n,n+1}\end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧a1,1x1+a1,2x2+⋯+a1,nxn=a1,n+1a2,1x1+a2,2x2+⋯+a2,nxn=a2,n+1…an,1x1+an,2x2+⋯+an,nxn=an,n+1
考虑将上述方程组记成矩阵形式(不懂没事,就是一个符号):
[ a 1 , 1 a 1 , 2 … a 1 , n ∣ a 1 , n + 1 a 2 , 1 a 2 , 2 … a 2 , n ∣ a 2 , n + 1 ⋮ ⋮ ⋱ ⋮ ∣ ⋮ a n , 1 a n , 2 … a n , n ∣ a n , n + 1 ] \begin{bmatrix}a_{1,1}&a_{1,2}&\dots&a_{1,n}&\mid&a_{1,n+1}\\a_{2,1}&a_{2,2}&\dots&a_{2,n}&\mid&a_{2,n+1}\\\vdots&\vdots&\ddots&\vdots&\mid&\vdots\\a_{n,1}&a_{n,2}&\dots&a_{n,n}&\mid&a_{n,n+1}\end{bmatrix} ⎣⎢⎢⎢⎡a1,1a2,1⋮an,1a1,2a2,2⋮an,2……⋱…a1,na2,n⋮an,n∣∣∣∣a1,n+1a2,n+1⋮an,n+1⎦⎥⎥⎥⎤
实际上就是把各项系数和常数项拎出来而已。
接下来我们需要一个消元的方法。
首先考虑消掉第一元。
将第二行的所有数跟第一行的所有数进行加减消元,将后面行的第一个主元系数化为 0。
这样就变成了这样:
[ ? ? … ? ∣ ? 0 ? … ? ∣ ? ⋮ ⋮ ⋱ ⋮ ∣ ? 0 ? … ? ∣ ? ] \begin{bmatrix}?&?&\dots&?&\mid&?\\0&?&\dots&?&\mid&?\\\vdots&\vdots&\ddots&\vdots&\mid&?\\0&?&\dots&?&\mid&?\end{bmatrix} ⎣⎢⎢⎢⎡?0⋮0??⋮?……⋱…??⋮?∣∣∣∣????⎦⎥⎥⎥⎤
如果 n = 4 n=4 n=4,那就是这样的:
[ ? ? ? ? ∣ ? 0 ? ? ? ∣ ? 0 ? ? ? ∣ ? 0 ? ? ? ∣ ? ] \begin{bmatrix}?&?&?&?&|&?\\0&?&?&?&|&?\\0&?&?&?&|&?\\0&?&?&?&|&?\end{bmatrix} ⎣⎢⎢⎡?000????????????∣∣∣∣????⎦⎥⎥⎤
然后考虑在后面 3 行里面加减消元消掉第二个主元,保留 3,4 两行,这样方程组就变成了这样:
[ ? ? ? ? ∣ ? 0 ? ? ? ∣ ? 0 0 ? ? ∣ ? 0 0 ? ? ∣ ? ] \begin{bmatrix}?&?&?&?&|&?\\0&?&?&?&|&?\\0&0&?&?&|&?\\0&0&?&?&|&?\end{bmatrix} ⎣⎢⎢⎡?000??00????????∣∣∣∣????⎦⎥⎥⎤
最后消掉第 3 个主元,就是这样的:
[ ? ? ? ? ∣ ? 0 ? ? ? ∣ ? 0 0 ? ? ∣ ? 0 0 0 ? ∣ ? ] \begin{bmatrix}?&?&?&?&|&?\\0&?&?&?&|&?\\0&0&?&?&|&?\\0&0&0&?&|&?\end{bmatrix} ⎣⎢⎢⎡?000??00???0????∣∣∣∣????⎦⎥⎥⎤
此时我们发现最后一行已经可以解出最后一个主元的解了,那么解出来。
然后不断向上反代即可。
这个图很像三角形对不对?
3. 高斯-约旦消元法
高斯消元法中我们采用了解出最后一个主元然后向上反代的过程解方程组。
但是实际上还有一种更加简洁的不用反代的方法,叫做高斯-约旦消元法。
首先还是看最后这个方程组:
[ ? ? ? ? ∣ ? 0 ? ? ? ∣ ? 0 0 ? ? ∣ ? 0 0 0 ? ∣ ? ] \begin{bmatrix}?&?&?&?&|&?\\0&?&?&?&|&?\\0&0&?&?&|&?\\0&0&0&?&|&?\end{bmatrix} ⎣⎢⎢⎡?000??00???0????∣∣∣∣????⎦⎥⎥⎤
这个时候我们发现,实际上对于第一行的后面 3 个主元,其可以跟第 2 行的主元加减消元消掉。
因此方程组就变成了这样:
[ ? 0 0 0 ∣ ? 0 ? ? ? ∣ ? 0 0 ? ? ∣ ? 0 0 0 ? ∣ ? ] \begin{bmatrix}?&0&0&0&|&?\\0&?&?&?&|&?\\0&0&?&?&|&?\\0&0&0&?&|&?\end{bmatrix} ⎣⎢⎢⎡?0000?000??00???∣∣∣∣????⎦⎥⎥⎤
不断消元,最后就变成了这样:
[ ? 0 0 0 ∣ ? 0 ? 0 0 ∣ ? 0 0 ? 0 ∣ ? 0 0 0 ? ∣ ? ] \begin{bmatrix}?&0&0&0&|&?\\0&?&0&0&|&?\\0&0&?&0&|&?\\0&0&0&?&|&?\end{bmatrix} ⎣⎢⎢⎡?0000?0000?0000?∣∣∣∣????⎦⎥⎥⎤
直接解就可以了。
这个图就是一条对角线。
上面考虑的都是有唯一解的情况,那么没有唯一解的情况呢?
没有唯一解分两种:无限多组解和根本没有解。
考虑一个一元一次方程 a x = b ax=b ax=b 的解的几种情况:
- 根本没有解: a = 0 , b ≠ 0 a=0,b \ne 0 a=0,b=0。
- 无限多组解: a = b = 0 a=b=0 a=b=0。
- 只有唯一解: a ≠ 0 a \ne 0 a=0。
因此我们可以根据这几个情况来判断方程组到底有没有解,有几组解。
在采用高斯-约旦消元法后,我们得到了 n n n 个一元一次方程,根据上述法则判断即可。
特别提醒:无解情况一定要在无限多组解之前算完!
模板题的代码(高斯-约旦消元法):GitHub CodeBase-of-Plozia P2455 [SDOI2006]线性方程组.cpp
4. 总结
- 高斯消元法:将方程组消元成三角形形式。
- 高斯-约旦消元法:将方程组消元成对角线形式。