高斯消元法&高斯-約旦消元法

高斯消元法和高斯-約旦消元法都是用來解形如算法

\[\left\{\begin{matrix} a_{1,1} x_1 & + & a_{1,2} x_2 & + & \cdots & + & a_{1,n} x_n & = & b_1 \\ a_{2,1} x_1 & + & a_{2,2} x_2 & + & \cdots & + & a_{2,n} x_n & = & b_2 \\ \vdots & & \vdots & & \ddots & & \vdots & = & \vdots \\ a_{n,1} x_1 & + & a_{n,2} x_2 & + & \cdots & + & a_{n,n} x_n & = & b_n \\ \end{matrix}\right.\]

的方程的解的。spa

兩個算法的比較

高斯消元法 高斯-約旦消元法
有無回代
能否判無解和無窮解 不可

也就是說,普通的高斯消元法須要回代,代碼比較繁瑣,但能夠分辨無解和無窮解;而高斯-約旦消元法則不須要回代,代碼較簡潔 (其實都挺簡潔的) 但在它眼裏無解和無窮解莫得區別。code

前置芝士

都是七下數學書裏的東西~數學

代入消元法

簡稱代入法
好比說,咱們有方程組\(\left\{\begin{matrix} ax+by=c \\ y=dx+e \\ \end{matrix}\right.\),其中 \(a,b,c,d,e\) 都是常數。那麼,咱們就能夠把 \(dx+e\) 代入到第一個方程,獲得方程 \(ax+b(dx+e)=c\),而後求解。
多元一次方程組同理io

加減消元法

簡稱加減法
又好比說,咱們有另外一個方程組\(\left\{\begin{matrix} ax+by=c \\ ax+dy=e \\ \end{matrix}\right.\)\(a,b,c,d,e\)依然都是常數。那麼,咱們就能夠把上式減下式(或下式減上式)獲得方程 \(by-dy=c-e\),而後求解。
又或者,再拿出來一個方程組\(\left\{\begin{matrix} ax+by=c \\ -ax+dy=e \end{matrix}\right.\)\(a,b,c,d,e\)都是常數,那麼,咱們就能夠把上式加下式,獲得方程 \(by+dy=c+e\),而後求解。
多元一次方程組同理table

普通高斯消元法

原理

以一個三元一次方程組爲例。class

\[\left\{\begin{matrix} 3x+2y+z=10 \\ 5x+y+6z=25 \\ 2x+3y+4z=20 \\ \end{matrix}\right.\]

咱們以 \(x,y,z\) 的順序一個個消,先消 \(x\)
首先咱們隨便拎一個方程出(通常拎要消的元的係數的絕對值最大的那個方程,這樣能夠減少精度損失(然鵝我並不知道爲何QwQ)):原理

\[5x+y+6z=25 \]

咱們要保留 \(5x\),而後把另外的方程中的 \(x\) 的係數變爲 \(0\)
使用加減法。
先拿①式減②式(咱們拎出來的那個) \(\times \frac{3}{5}\)(這樣才能消去 \(x\)):方法

\[(3-\frac{3}{5} \times 5)x + (2-\frac{3}{5} \times 1)y + (1-\frac{3}{5} \times 6)z = 10 - \frac{3}{5} \times 25 \]

獲得im

\[0x+\frac{7}{5}y+(-\frac{13}{5})z=-5 \]

再把這個方程做爲新的①式。
而後再以一樣的方法消③式,得

\[\left\{\begin{matrix} 0x+\frac{7}{5}y+(-\frac{13}{5})z=-5 \\ 5x+y+6z=25 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ \end{matrix}\right.\]


接着,再消 \(y\),拎出③式,而後減一減(②式不用減),得

\[\left\{\begin{matrix} 0x+0y+(-\frac{225}{65})z=-\frac{135}{13} \\ 5x+y+6z=25 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ \end{matrix}\right.\]


這時,咱們發現①式只剩下 \(z\) 了,因而咱們能夠解出

\[z=3 \]

而後代入③式,就能夠解得

\[y=2 \]

再把它們代入②式,解得

\[x=1 \]

形式化過程

上面的過程是否是顯得雜亂無章?
那麼讓咱們把他形式化。
先找到 \(x\) 的係數的絕對值最大的方程,放到最前面

\[\left\{\begin{matrix} 5x+y+6z=25 \\ 3x+2y+z=10 \\ 2x+3y+4z=20 \\ \end{matrix}\right.\]

用它消掉下面的式子的 \(x\)

\[\left\{\begin{matrix} 5x+y+6z=25 \\ 0x+\frac{7}{5}y+(-\frac{13}{5})z=-5 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ \end{matrix}\right.\]


解的過程當中若是拎出來的式子要消的元爲 \(0\),則無解或有無窮解(由於拎出來的方程的元的係數的絕對值已經最大了仍是 \(0\),因此其餘的也就都是 \(0\) 了(感性理解下QwQ?))


而後再找到剩下的方程中 \(y\) 的係數的絕對值最大的那個,提上來

\[\left\{\begin{matrix} 5x+y+6z=25 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ 0x+\frac{7}{5}y+(-\frac{13}{5})z=-5 \\ \end{matrix}\right.\]

而後消掉它下面的式子的 \(y\)

\[\left\{\begin{matrix} 5x+y+6z=25 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ 0x+0y+(-\frac{225}{65})z=-\frac{135}{13} \\ \end{matrix}\right.\]


而後一步步代入,解方程。
最後這一步咱們把它叫作回代

代碼實現

代碼實現又有些不一樣。
上面的介紹中是在最後才把係數化爲 \(1\) 的,但實際上,咱們在選好方程的時候,就能夠把係數化爲 \(1\) 了,這樣還能夠減小碼量。

//n表示未知數的數量
//a[i][j]表明第i個方程中第j個未知數的係數(其實和開頭給出的格式同樣啦~),特殊的,a[i][n+1]表示等式的右邊
	for(int i=1;i<=n;i++)
	{
		int res=i;
		for(int k=i+1;k<=n;k++)
			if(Abs(a[k][i])>Abs(a[res][i])) res=k;
		for(int j=1;j<=n+1;j++) swap(a[i][j],a[res][j]);
		if(a[i][i]==0){puts("No Solution");return 0;}
		for(int j=i+1;j<=n+1;j++) a[i][j]/=a[i][i];
		a[i][i]=1;
		for(int k=i+1;k<=n;k++)
		{
			for(int j=i+1;j<=n+1;j++) a[k][j]-=a[k][i]*a[i][j];
			a[k][i]=0;
		}
	}
	for(int i=n-1;i>=1;i--)
		for(int k=i+1;k<=n;k++)
			a[i][n+1]-=a[i][k]*a[k][n+1];

判無解仍是無窮解

在回代完後掃一遍,若是遇到 \(a_{i,i}=0\)\(a_{i,n+1}=0\) 則有無窮解,若是遇到 \(a_{i,i}=0\)\(a_{i,n+1} \not= 0\) 則無解。
注意,若是一個方程無解則整個方程組都無解,因此要先判無解再判無窮解。
不過好像仍是會被某些毒瘤數據卡掉的說
因此要打壓這種毒瘤題!

高斯-約旦消元法

原理

\[\left\{\begin{matrix} 3x+2y+z=10 \\ 5x+y+6z=25 \\ 2x+3y+4z=20 \\ \end{matrix}\right.\]

仍是這個方程組爲例。
咱們也保留要消的元的係數絕對值最大的那個方程,而後排下順序就是

\[\left\{\begin{matrix} 5x+y+6z=25 \\ 2x+3y+4z=20 \\ 3x+2y+z=10 \\ \end{matrix}\right.\]

(注意原本 \(z\) 係數最大應該是 \(5x+y+6z=25\) 的,可是他被 \(x\) 搶走了)

咱們先消 \(x\)
首先咱們把選出的方程 \(5x+y+6z=25\)\(x\) 的係數化爲 \(1\)

\[x+\frac{1}{5}y+\frac{6}{5}z=5 \]

而後呢,把全部的方程都與它相減使其 \(x\) 的係數變爲 \(1\),也是拿一個式子減這個式子乘多少多少,就不細講了:

\[\left\{\begin{matrix} x+\frac{1}{5}y+\frac{6}{5}z=5 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ 3x+2y+z=10 \\ \end{matrix}\right.\]

\[\Downarrow \]

\[\left\{\begin{matrix} x+\frac{1}{5}y+\frac{6}{5}z=5 \\ 0x+\frac{13}{5}y+\frac{8}{5}z=10 \\ 0x+\frac{7}{5}y+(-\frac{13}{5}z)=-5 \\ \end{matrix}\right.\]

而後消 \(y\)

\[\left\{\begin{matrix} x+\frac{1}{5}y+\frac{6}{5}z=5 \\ 0x+y+\frac{8}{13}z=\frac{50}{13} \\ 0x+\frac{7}{5}y+(-\frac{13}{5}z)=-5 \\ \end{matrix}\right.\]

注意除了選擇的那個方程,要把其餘全部的方程的 \(y\) 的係數都變成 \(0\) 哦。

\[\left\{\begin{matrix} x+0y+\frac{70}{65}z=\frac{275}{65} \\ 0x+y+\frac{8}{13}z=\frac{50}{13} \\ 0x+\frac{7}{5}y+(-\frac{13}{5}z)=-5 \\ \end{matrix}\right.\]

\[\Downarrow \]

\[\left\{\begin{matrix} x+0y+\frac{70}{65}z=\frac{275}{65} \\ 0x+y+\frac{8}{13}z=\frac{50}{13} \\ 0x+0y+(-\frac{225}{65}z)=-\frac{135}{13} \\ \end{matrix}\right.\]

最後消 \(z\)

\[\left\{\begin{matrix} x+0y+\frac{70}{65}z=\frac{275}{65} \\ 0x+y+\frac{8}{13}z=\frac{50}{13} \\ 0x+0y+z=3 \\ \end{matrix}\right.\]

\[\Downarrow \]

\[\left\{\begin{matrix} x+0y+0z=1 \\ 0x+y+0z=2 \\ 0x+0y+z=3 \\ \end{matrix}\right.\]

因而就能獲得答案:

\[x=1,y=2,z=3 \]

因此和普通高斯消元比起來,高斯-約旦消元真的方便好多

代碼實現

然鵝實現起來好像差很少(((

//n表示未知數的數量
//a[i][j]表明第i個方程中第j個未知數的係數(其實和開頭給出的格式同樣啦~),特殊的,a[i][n+1]表示等式的右邊
	for(int i=1;i<=n;i++)
	{
		int res=i;
		for(int k=i+1;k<=n;k++)
			if(Abs(a[k][i])>Abs(a[res][i])) res=k;
		for(int j=1;j<=n+1;j++) swap(a[i][j],a[res][j]);
		if(a[i][i]==0){puts("No Solution");return 0;}
		for(int j=i+1;j<=n+1;j++) a[i][j]/=a[i][i];
		a[i][i]=1;
		for(int k=1;k<=n;k++)
			if(k!=i)
			{
				for(int j=i+1;j<=n+1;j++) a[k][j]-=a[k][i]*a[i][j];
				a[k][i]=0;
			}
	}
相關文章
相關標籤/搜索