Gauss消元法

今天我們來聊聊數值方法裏面一個很經典的問題,求解線性方程組。線性方程組是線代裏面那個很重要的知識,而它本身的意義重大,在很多領域都會用到。求解問題,不知引出了多少數學分支,而線性方程組是一個很經典的求解問題,當然相對於其他的求解問題,它相對來說也簡單很多,但是由它引領的知識卻無比龐大…先看看線性方程組的用處吧:

  • 用最小二乘法對實驗離散數據進行擬合時候會用到線性方程組
  • 諸多的插值問題也會用到線性方程組
  • 還有我們高中就開始接觸的生產與投入的問題。
  • 在建築、機械結構的設計需要計算線性方程組

線性方程組

我們把下面的方程組稱爲線性方程組,注意到它有以下的特點:

  • 每個未知量的次數爲1。
  • 係數都是常數
    如果方程組中共有n個未知量,就稱爲n元線性方程組。

{a11x1+a12x1+...+a1nx1=b1a21x1+a22x1+...+a2nx1=b2.........=...an1x1+an2x1+...+annx1=bn\left\{\begin{matrix} a_{11}x_1+ & a_{12}x_1+ & ...+ & a_{1n}x_1&=b_1\\ a_{21}x_1+ & a_{22}x_1+ & ...+ & a_{2n}x_1&=b_2\\ ...& ... & &...&=...\\ a_{n1}x_1+ & a_{n2}x_1+ & ...+ & a_{nn}x_1&=b_n\\ \end{matrix}\right.

求解線性方程組的其中兩種解法:

求解線性方程組的方法不只兩種,但是我在這裏介紹兩種,一種是Cramer法則,一種是Gauss消元法。

  • Cramer法則:本該在線代裏面學過,但是如果你忘了或者是根本沒有學好,請移步到https://blog.csdn.net/jackghq/article/details/90712570,這是CSDN中總結了Cramer法則的一篇較好的文章。
  • 高斯消元法:高斯消元法相對於Cramer法則來說大大減少了時間複雜度,尤其是在使用計算機進行計算的時候,效果更加顯著。我們主要學習高斯消元法。

幾個要談的問題:

設計算法的時候,我們要注意以下幾個問題:

  • 儘量不要把兩個相近的數進行相減。兩個及其相近的數進行相減,會使有效數字嚴重損失。其實有很多問題,我們都可以通過形變去改變其運算,而不會是它們相減。
  • 儘量不要使用大數去加上一個小數。主要原因是因爲,由於捨去誤差(計算機有一定的精度),當一個大數加上一個小數的時候,會使的小數根本沒有發揮作用。我們可以用小數除以大數。
  • 儘量不要除以一個絕對值很小的數。除以一個很小的數,結果會很大很大,就會產生溢出現象
  • 減少運算次數,也就是說減少時間複雜度。另外,運算次數多,每次運算都要產生無可避免的捨去誤差,當誤差積累時就會結果失真。
  • 選用數值穩定的式子。式子儘量收斂或者可控。所以儘量不要使用連加或者連乘的方式。

直接方法:

  • 什麼叫做直接方法?
    直接方法就是忽略捨去誤差、可以求出精確值的方法,本次主要討論兩個直接方法,一個是Cramer法則,另一個就是gauss消元法。
  • 但是有個問題:
    就站在上述的第四條問題的觀點上,我們看看Cramer需要多大的計算量:
    按照行列式的定義計算(n個不同行不同列的元素外加一個符號),共有(n1)n!(n-1)n!次,然後根據Cramer法則就有(n+1)(n1)n!(n+1)(n-1)n!次,如果有加入n=20,就需要約9.7×10209.7\times10^{20}次運算。如果一臺計算機每秒可以計算120億次,則約需要計算2500年,這是不可能完成的任務。
    所以Cramer法則的缺點就顯而易見了。那麼,沒有了Cramer法則,那麼我們有應該怎樣計算20階的線性方程組呢?
  • 這時候,我們的高斯消元法就出來了。

高斯消元法:

高斯消元是一種相對於Cramer法則來說,可以減少很多的計算量。實際上我們在中學的時候就學過了高斯消元法。

高斯消元法的一般步驟:

我們主要的思想就是使用逐個消元的方法,把方程組化成階梯型的方程組。(主要使用初等行變換)
我們先記行列式AAaija_{ij}記成aij(1)a_{ij}^{(1)},以後每進行一次初等行變換一次a的上標就增加一次。
首先對方程組Ax=bAx=b,取其增廣矩陣(A,b)(A,b),其中(A,b)(A,b)爲:

(a11(1)a12(1)...a1n(1)b1(1)a21(1)a22(1)...a2n(1)b2(1)............an1(1)an2(1)...ann(1)bn(1))\begin{pmatrix} a_{11} ^{(1)}& a_{12} ^{(1)}& ... & a_{1n} ^{(1)}&b_1 ^{(1)}\\ a_{21} ^{(1)}& a_{22} ^{(1)}& ... & a_{2n} ^{(1)}&b_2 ^{(1)}\\ ...& ... & &...&...\\ a_{n1} ^{(1)} & a_{n2} ^{(1)}& ... & a_{nn} ^{(1)}&b_n ^{(1)}\\ \end{pmatrix}

第一次把第一列除a11a_{11}的元素,全部化爲0,如下:
(a11(1)a12(1)...a1n(1)b1(1)a22(2)...a2n(2)b2(2)............an2(2)...ann(2)bn(2))\begin{pmatrix} a_{11} ^{(1)}& a_{12} ^{(1)}& ... & a_{1n} ^{(1)}&b_1 ^{(1)}\\ & a_{22} ^{(2)}& ... & a_{2n} ^{(2)}&b_2 ^{(2)}\\ ...& ... & &...&...\\ & a_{n2} ^{(2)}& ... & a_{nn} ^{(2)}&b_n ^{(2)}\\ \end{pmatrix}

第二次把第二列的a22a_{22}下面的元素全部化爲零:

(a11(1)a12(1)a23(1)...a1n(1)b1(1)a22(2)a23(2)...a2n(2)b2(2)a33(3)...a3n(3)b3(3)...............an3(3)...ann(3)bn(3))\begin{pmatrix} a_{11} ^{(1)}& a_{12} ^{(1)}& a_{23}^{(1)}&... & a_{1n} ^{(1)}&b_1 ^{(1)}\\ & a_{22} ^{(2)}&a_{23}^{(2)}& ... & a_{2n} ^{(2)}&b_2 ^{(2)}\\ & & a_{33}^{(3)}&... & a_{3n}^{(3)}&b_3^{(3)}\\ ...& ... &...& &...&...\\ && a_{n3}^{(3)}&... & a_{nn} ^{(3)}&b_n ^{(3)}\\ \end{pmatrix}


如此進行下去:
得到:

(a11(1)a12(1)a23(1)...a1n(1)b1(1)a22(2)a23(2)...a2n(2)b2(2)a33(3)...a3n(3)b3(3)..................ann(n1)bn(n1))\begin{pmatrix} a_{11} ^{(1)}& a_{12} ^{(1)}& a_{23}^{(1)}&... & a_{1n} ^{(1)}&b_1 ^{(1)}\\ & a_{22} ^{(2)}&a_{23}^{(2)}& ... & a_{2n} ^{(2)}&b_2 ^{(2)}\\ & & a_{33}^{(3)}&... & a_{3n}^{(3)}&b_3^{(3)}\\ ...& ... &...& &...&...\\ && &... & a_{nn} ^{(n-1)}&b_n ^{(n-1)}\\ \end{pmatrix}

得到上面的一個階梯矩陣。

第二步:
回代便可以得到一個解。

高斯消元法的計算量:

因爲我們在每個元素上標了計算次數,我們得到,一般情況下我們進行了:i=2n(i21)+i=1ni\sum_{i=2}^{n}(i^2-1)+\sum_{i=1}^{n}i次,如果n=20,則需要3060次運算,對於計算機也就是一瞬間的事。產生的誤差也相對會少很多。

高斯消元法的一些完善:

  • 其實如果上述的akka_{kk}不爲零,則不能進行消元,我們成行列指標相同的元素稱爲列主元。
  • 列主元爲零的情況下,可以先跟下面的行(同列元素不爲零)進行一次對換。
  • 在計算機計算的過程中,我們又要考慮精度問題,所以我們取一個最小整數eps,使得當列主元素小於eps時,便跟列指標大於k的同列元素最大的行進行對換。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章