对于n元线性方程组
{ a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n = b 2 ⋯ a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n = b n (3.1) \begin{cases} a_{11}x_1 +a_{12}x_2+\cdots+a_{1n}x_n = b_1\\ a_{21}x_1 +a_{22}x_2+\cdots+a_{2n}x_n = b_2\\ \cdots\\ a_{n1}x_1 +a_{n2}x_2+\cdots+a_{nn}x_n = b_n\\ \end{cases}\tag{3.1} ⎩ ⎨ ⎧a11x1+a12x2+⋯+a1nxn=b1a21x1+a22x2+⋯+a2nxn=b2⋯an1x1+an2x2+⋯+annxn=bn(3.1)
式中, a i j a_{ij} aij和 b i j , ( i , j = 1 , 2 , … , n ) b_{ij},(i,j=1,2,…,n) bij,(i,j=1,2,…,n)为常数, x i ( i = 1 , 2 , … , n ) x_{i}(i=1,2,…,n) xi(i=1,2,…,n)为待求的未知量.若写成矩阵形式,则为
A ⃗ = ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋯ ⋯ ⋯ ⋯ a n 1 a n 2 ⋯ a n n ) , x ⃗ = ( x 1 x 2 ⋮ x n ) , b ⃗ = ( b 1 b 2 ⋮ b n ) \vec{A }= \begin{pmatrix} a_{11} & a_{12} & \cdots& a_{1n}\\ a_{21} & a_{22} & \cdots& a_{2n}\\ \cdots & \cdots & \cdots& \cdots \\ a_{n1} & a_{n2} & \cdots& a_{nn}\\ \end{pmatrix}, \vec{x }=\begin{pmatrix} x_1\\ x_2\\ \vdots\\ x_n \end{pmatrix}, \vec{b}=\begin{pmatrix} b_1\\ b_2\\ \vdots\\ b _n \end{pmatrix} A=⎝ ⎛a11a21⋯an1a12a22⋯an2⋯⋯⋯⋯a1na2n⋯ann⎠ ⎞,x=⎝ ⎛x1x2⋮xn⎠ ⎞,b=⎝ ⎛b1b2⋮bn⎠ ⎞
有时也把式(3.1)写成增广矩阵的形式
A ⃗ = ( a 11 a 12 ⋯ a 1 n b 1 a 21 a 22 ⋯ a 2 n b 2 ⋯ ⋯ ⋯ ⋯ ⋯ a n 1 a n 2 ⋯ a n n b n ) (3.2) \vec{A }= \begin{pmatrix} a_{11} & a_{12} & \cdots& a_{1n}& b_1\\ a_{21} & a_{22} & \cdots& a_{2n}& b_2\\ \cdots & \cdots & \cdots& \cdots &\cdots\\ a_{n1} & a_{n2} & \cdots& a_{nn}& b_n\\ \end{pmatrix}\tag{3.2} A=⎝ ⎛a11a21⋯an1a12a22⋯an2⋯⋯⋯⋯a1na2n⋯annb1b2⋯bn⎠ ⎞(3.2)
由克莱姆法则可知,方程组(3.1)存在唯一解
x i = d e t A i d e t A , i = 1 , 2 , ⋯ , n x_i= \frac{det A_i}{det A},i=1,2,\cdots,n xi=detAdetAi,i=1,2,⋯,n
式中, A A A是系数矩阵 A A A中第 i i i列元素换为右端系数 b b b 得到的矩阵.但用克莱姆法则求解方程组(3.1)时要进行 n ! ( n − 1 ) + n n!(n-1)+n n!(n−1)+n次乘除法运算.当 n n n较大时,计算量之大达到惊人的程度.若 n = 20 n=20 n=20,大约需要接近 21 ! 21! 21!次乘除法,因而此方法难以使用,必须研究其他数值方法.
线性方程组的数值解法一般分为两类.
直接法
直接法又称精确法,是指在假设没有舍入误差的条件下,经过有限步算术运算求得方程组准确解的一类方法.但由于实际计算时舍入误差是不可避免的,因此直接法也只能得到近似解.目前较常用的直接法是高斯消去法及三角分解法。
迭代法
迭代法又称为间接法,是指先从一个给定的初始值开始,然后用某种极限过程去逼近方程组准确解的一类方法.这类方法编程较容易,但要考虑迭代过程的收敛性、收敛速度等问题.由于实际计算时只能进行有限步的计算,因此得到的也是近似解.当线性方程组的系数矩阵阶数高、零元素比较多的时候(即系数矩阵为高阶稀疏矩阵),一般优先考虑迭代法.目前常用的迭代法有雅可比迭代法、高斯-赛德尔迭代法、超松弛迭代法和梯度法.
高斯(Gauss)消去法的基本思想是通过消元把线性方程组化为等价的上三角方程组,再进行求解.高斯消去法一般由“消元过程”和“回代过程”两部分组成。消元过程就是按确定的计算过程对方程组的增广矩阵进行初等行变换,将原方程组化为与之等价的上三角方程组;回代过程就是对得到的上三角方程组求解的过程.
下面先介绍一个简单实例,然后再推广到一般n元方程组,以说明高斯消去法的基本思路.
例1 使用高斯消去法求解下列方程组
{ 7 x 1 + 8 x 2 + 11 x 3 = − 3 5 x 1 + x 2 − 3 x 3 = − 4 x 1 + 2 x 2 + 3 x 3 = 1 (3.3) \begin{cases} 7x_1 +8x_2+11x_3 =-3\\ 5x_1 +x_2-3x_3 =-4\\ x_1 +2x_2+3x_3 =1\\ \end{cases}\tag{3.3} ⎩ ⎨ ⎧7x1+8x2+11x3=−35x1+x2−3x3=−4x1+2x2+3x3=1(3.3)
解 消元过程的第1步:保持第1个方程不动消去线性方程组(3.3)第2、3个方程
中的 x 1 x_1 x1,即将第2、3个方程 x 1 x_1 x1项的系数除以第1个方程 x 1 x_1 x1项的系数,得到比例系数 m 21 m_{21} m21,和 m 31 m_{31} m31
m 21 = 5 7 , m 31 = = 1 7 m_{21}=\frac{5}{7},m_{31}==\frac{1}{7} m21=75,m31==71
用第2、3个方程分别减去比例系数 m 21 m_{21} m21,和 m 31 m_{31} m31乘以第1个方程后得到的方程,这样就消去了第2、3个方程的 x 1 x_1 x1项,得到等价方程组
{ 7 x 1 + 8 x 2 + 11 x 3 = − 3 − 33 7 x 2 − 76 7 x 3 = − 13 7 6 7 x 2 + 10 7 x 3 = 10 7 (3.4) \begin{cases} 7x_1 +8x_2+11x_3 =-3\\ -\frac{33}{7}x_2-\frac{76}{7}x_3 =-\frac{13}{7}\\ \frac{6}{7}x_2+\frac{10}{7}x_3 =\frac{10}{7}\\ \end{cases}\tag{3.4} ⎩ ⎨ ⎧7x1+8x2+11x3=−3−733x2−776x3=−71376x2+710x3=710(3.4)
消元过程的第2步:在得到的等价方程组(3.4)中,保持第1、2个方程不动,消去线性方程组(3.4)中的第3个方程中的 x 2 x_2 x2即将第3个方程 x 2 x_2 x2项的系数除以第2个方程 x 2 x_2 x2项的系数,得到比例系数 m 32 m_{32} m32
m 32 = − 6 33 m_{32}=-\frac{6}{33} m32=−336
用第3个方程减去其比例系数 m 32 m_{32} m32乘以第2个方程得到的方程,这样就消去第3个方程的 x 2 x_2 x2项,得到等价方程组
{ 7 x 1 + 8 x 2 + 11 x 3 = − 3 − 33 7 x 2 − 76 7 x 3 = − 13 7 − 6 11 x 3 = 12 11 (3.5) \begin{cases} 7x_1 +8x_2+11x_3 =-3\\ -\frac{33}{7}x_2-\frac{76}{7}x_3 =-\frac{13}{7}\\ -\frac{6}{11}x_3 =\frac{12}{11}\\ \end{cases}\tag{3.5} ⎩ ⎨ ⎧7x1+8x2+11x3=−3−733x2−776x3=−713−116x3=1112(3.5)
这样,消元过程就是将原方程组化为上三角形方程组(3.5)的过程,其系数矩阵是上三角矩阵.回代过程就是将上三角方程组自下而上求解的过程,从而得出
( x 1 x 2 x 3 ) = ( − 3 5 − 2 ) \begin{pmatrix} x_1\\ x_2\\ x_3 \end{pmatrix}=\begin{pmatrix} -3\\ 5\\ -2 \end{pmatrix} ⎝ ⎛x1x2x3⎠ ⎞=⎝ ⎛−35−2⎠ ⎞
以上的消元过程相当于对增广矩阵进行了初等行变换
( 7 8 11 − 3 5 1 − 3 − 4 1 2 3 1 ) —— > ( 7 8 11 − 3 − 33 7 − 76 7 − 13 7 − 6 11 12 11 ) \begin{pmatrix} 7& 8&11& -3\\ 5& 1&-3& -4\\ 1& 2&3& 1\\ \end{pmatrix}——>\begin{pmatrix} 7& 8&11& -3\\ & -\frac{33}{7}&-\frac{76}{7}& -\frac{13}{7}\\ & &-\frac{6}{11}& \frac{12}{11}\\ \end{pmatrix} ⎝ ⎛75181211−33−3−41⎠ ⎞——>⎝ ⎛78−73311−776−116−3−7131112⎠ ⎞
( a 11 ( 1 ) a 12 ( 1 ) ⋯ a 1 n ( 1 ) a 21 ( 1 ) a 22 ( 1 ) ⋯ a 2 n ( 1 ) ⋯ ⋯ ⋯ ⋯ a n 1 ( 1 ) a n 2 ( 1 ) ⋯ a n n ( 1 ) ) ( x 1 x 2 ⋮ x n ) = ( b 1 ( 1 ) b 2 ( 1 ) ⋮ b n ( 1 ) ) \begin{pmatrix} a_{11}^{(1)} & a_{12}^{(1)} & \cdots& a_{1n}^{(1)}\\ a_{21}^{(1)} & a_{22}^{(1)} & \cdots& a_{2n}^{(1)}\\ \cdots & \cdots & \cdots& \cdots \\ a_{n1}^{(1)} & a_{n2}^{(1)} & \cdots& a_{nn}^{(1)}\\ \end{pmatrix}\begin{pmatrix} x_1\\ x_2\\ \vdots\\ x_n \end{pmatrix}=\begin{pmatrix} b_1^{(1)} \\ b_2^{(1)} \\ \vdots\\ b _n^{(1)} \end{pmatrix} ⎝ ⎛a11(1)a21(1)⋯an1(1)a12(1)a22(1)⋯an2(1)⋯⋯⋯⋯a1n(1)a2n(1)⋯ann(1)⎠ ⎞⎝ ⎛x1x2⋮xn⎠ ⎞=⎝ ⎛b1(1)b2(1)⋮bn(1)⎠ ⎞
记 A x = b Ax=b Ax=b为 A x = b ′ Ax =b' Ax=b′,其中 A R AR AR和 b b b的元素分别记为 a i j ( k ) a_{ij}(k) aij(k)和 b i ( k ) , ( i , j = 1 , 2 … , n ) b_i^{(k)}, (i,j=1,2…,n) bi(k),(i,j=1,2…,n),系数上标 ( k ) (k) (k)代表第 k k k次消元前的初状态,经过矩阵的初等行变换进行消元后,得到
( a 11 ( 1 ) a 12 ( 1 ) ⋯ a 1 n ( 1 ) a 22 ( 2 ) ⋯ a 2 n ( 2 ) ⋱ ⋮ a n n ( n ) ) ( x 1 x 2 ⋮ x n ) = ( b 1 ( 1 ) b 2 ( 2 ) ⋮ b n ( n ) ) (3.6) \begin{pmatrix} a_{11}^{(1)} & a_{12}^{(1)} & \cdots& a_{1n}^{(1)}\\ & a_{22}^{(2)} & \cdots& a_{2n}^{(2)}\\ & & \ddots& \vdots \\ & & & a_{nn}^{(n)}\\ \end{pmatrix}\begin{pmatrix} x_1\\ x_2\\ \vdots\\ x_n \end{pmatrix}=\begin{pmatrix} b_1^{(1)} \\ b_2^{(2)} \\ \vdots\\ b _n^{(n)} \end{pmatrix}\tag{3.6} ⎝ ⎛a11(1)a12(1)a22(2)⋯⋯⋱a1n(1)a2n(2)⋮ann(n)⎠ ⎞⎝ ⎛x1x2⋮xn⎠ ⎞=⎝ ⎛b1(1)b2(2)⋮bn(n)⎠ ⎞(3.6)
消元过程结束后,只要 a k k ( k ) ≠ 0 a_kk^(k)≠0 akk(k)=0,对上三角方程组就可以自下而上逐步回代,依次求得 x n , x n − 1 ⋯ , x 1 x_n,x_{n-1}\cdots,x_1 xn,xn−1⋯,x1,回代公式如下
{ x n = b n ( n ) a n n ( n ) x k = b k ( k ) − ∑ j = k + 1 n a k j ( k ) x j a k k ( k ) , k = n − 1 , ⋯ , 2 , 1 (3..7) \begin{cases} x_n=\frac{b_n^{(n)}}{a_{nn}^{(n)}}\\ x_k=\frac{b_k^{(k)}-\sum\limits_{j=k+1}^na_{kj}^{(k)}x_j}{a_{kk}^{(k)}},k=n-1,\cdots,2,1 \end{cases}\tag{3..7} ⎩ ⎨ ⎧xn=ann(n)bn(n)xk=akk(k)bk(k)−j=k+1∑nakj(k)xj,k=n−1,⋯,2,1(3..7)
a k k ( k ) ( k = 1 , 2 , ⋯ , n ) a_{kk}^{(k)}(k=1,2,\cdots,n) akk(k)(k=1,2,⋯,n)称为各次消元的主元素, m i k ( k = 1 , 2 , ⋯ , n ) m_{ik}(k=1,2,\cdots,n) mik(k=1,2,⋯,n)称为各次消元的比例系数,主元素所在的行称为主行.
以上消元和回代过程总的乘除法次数为量为 n 3 3 + n 2 − n 3 \frac{n^3}{3}+n^2-\frac{n}{3} 3n3+n2−3n,当n很大时,高斯消去法的计算量为 n 3 3 \frac{n^3}{3} 3n3数量级,与克莱姆法则相比,高斯消去法的计算量大为减少.若用高斯消去法计算 n = 20 n=20 n=20的线性方程组,只需要3060次乘除法的运算即可完成.
前面介绍的高斯消去法,一直是在假设 a k k ( k ) ≠ 0 a_{kk}^{(k)}\neq0 akk(k)=0情况下进行的,并且按照方程组中各方程给定的顺序进行.当主元素 a k k ( k ) = 0 a_{kk}^{(k)}=0 akk(k)=0,消元过程就无法进行.即使 a k k ( k ) ≠ 0 a_{kk}^{(k)}\neq 0 akk(k)=0,但当其绝对值很小时,用它作为除数会导致其他元素的数量级激增和舍入误差扩大,严重影响计算结果的精度.实用的高斯消去法应在按列消元过程的每一步,都在可能范围内选择绝对值较大的元素作为主元,再使用高斯消去法,这就是列主元高斯消去法的基本思想.
import numpy as np
def ColP_Gauss_Elim(eq_set):
line, col = eq_set.shape[0], eq_set.shape[1] # 获取方程组的行数和列数
for k in range(0, line): #换行
col_P_index = np.argmax(eq_set[k:, k])
eq_set[[k, col_P_index + k], :] = eq_set[[col_P_index + k, k], :]
for i in range(0, line): #消元
n = 1
while i + n < line:
eq_set[i + n] = eq_set[i + n] * eq_set[i][i] - eq_set[i] * eq_set[i + n][i]
n += 1
for k in range(line - 1, -1, -1): # 回代求解
eq_set[k] = eq_set[k] / eq_set[k][k]
for i in range(k - 1, -1, -1):
eq_set[i] = eq_set[i] - eq_set[k] * eq_set[i][k]
print(eq_set)
例2 用列主元高斯消去法求解线性方程组
{ 12 x 1 − 3 x 2 + 3 x 3 = 15 18 x 1 − 3 x 2 + x 3 = 15 − x 1 + 2 x 2 + x 3 = 6 \begin{cases} 12x_1-3x_2+3x_3 = 15\\ 18x_1-3x_2+x_3 = 15\\ -x_1+2x_2+x_3 = 6 \end{cases} ⎩ ⎨ ⎧12x1−3x2+3x3=1518x1−3x2+x3=15−x1+2x2+x3=6
解我们输入下面的numpy数组,调用函数进行求解
eq_set = np.array([[12, -3, 3, 15], [18, -3, 1, 15], [-1, 2, 1, 6]])
ColP_Gauss_Elim(eq_set)
答案为
[[1 0 0 1]
[0 1 0 2]
[0 0 1 3]]
即
( x 1 , x 2 , x 3 ) T = ( 1 , 2 , 3 ) T \begin{pmatrix} x_1,x_2,x_3\end{pmatrix}^T=\begin{pmatrix} 1,2,3\end{pmatrix}^T (x1,x2,x3)T=(1,2,3)T