給定 \(n\) 元一次方程組
\[\begin
a_x_1+a_x_2+\cdots+a_x_n=b_1\\
a_x_1+a_x_2+\cdots+a_x_n=b_2\\
\cdots\\
a_x_1+a_x_2+\cdots+a_x_n=b_n\\
\end
\]請求出方程組的解的情況:
對於這樣的問題,我們可以使用高斯消元法進行求解,當然高斯消元法有乙個回代的過程,**略長,而且精度較低。
所以我們隆重推出高斯-約旦消元法!!!
回顧一下我們是怎麼手算的,一般用的都是加減消元法,普通高斯和高斯-約旦用的都是加減消元。
在此之前,我們需要了解一下矩陣初等變換。
交換矩陣的兩行;
用乙個非零數 \(k\) 乘矩陣的某一行所有元素;
把矩陣的某一行所有元素乘以乙個數 \(k\) 後加到另一行對應的同一列的元素上;
類似地,把以上的行
改為列
便得到矩陣初等列變換的定義。
矩陣初等行變換與初等列變換合稱為矩陣初等變換。
若矩陣 \(a\) 經過有限次的初等行變換變為矩陣 \(b\),則矩陣 \(a\) 與矩陣 \(b\)行等價;若矩陣 \(a\) 經過有限次的初等列變換變為矩陣 \(b\),則矩陣 \(a\) 與矩陣 \(b\)列等價;若矩陣 \(a\) 經過有限次的初等變換變為矩陣 \(b\),則矩陣 \(a\) 與矩陣 \(b\)等價。
當然列的用不著
首先有乙個由係數構成的 \(n\times n\) 的矩陣
\[\begin
a_&a_&\cdots&a_\\
a_&a_&\cdots&a_\\
\vdots&\vdots&\ddots&\vdots\\
a_&a_&\cdots&a_\\
\end
\]然後是乙個由常數構成的 \(n\times 1\) 的列向量
\[\begin
b_1\\
b_2\\
\vdots\\
b_n\end
\]把它們放在一起構成乙個 \(n\times(n+1)\) 的增廣矩陣:
\[\begin
a_&a_&\cdots&a_&\mid&b_1\\
a_&a_&\cdots&a_&\mid&b_2\\
\vdots&\vdots&\ddots&\vdots&\mid&\vdots\\
a_&a_&\cdots&a_&\mid&b_n\\
\end
\]我們遍歷每一列,對於第 \(i\) 列選出最大的未處理過的行上的數作為主元,意味著加減消元後除了主元這一行外其他行的第 \(i\) 列都為 \(0\)。
選最大的作為主元的原因是避免精度誤差。
然後就是加減消元了。
舉個例子
\[\begin
2x-y+z=1\\
4x+y-z=5\\
x+y+z=0
\end
\]增廣矩陣就是
\[\begin
2&-1&1&\mid&1\\
4&1&-1&\mid&5\\
1&1&1&\mid&0
\end
\]先是第 \(1\) 列,選 \(4\) 為主元。
\(4\) 在第 \(2\) 行,將第 \(2\) 行與第 \(1\) 行交換。
\[\begin
4&1&-1&\mid&5\\
2&-1&1&\mid&1\\
1&1&1&\mid&0
\end
\]對於第 \(2\) 行,第一列上的 \(2\) 是 \(4\) 的 \(\dfrac\)。
\[\begin
4&1&-1&\mid&5\\
2-4\times\dfrac&-1-1\times\dfrac&1-(-1)\times\dfrac&\mid&1-5\times\dfrac\\
1&1&1&\mid&0
\end
\]化簡得
\[\begin
4&1&-1&\mid&5\\
0&-\dfrac&\dfrac&\mid&-\dfrac\\
1&1&1&\mid&0
\end
\]對第 \(3\) 行的處理同理
\[\begin
4&1&-1&\mid&5\\
0&-\dfrac&\dfrac&\mid&-\dfrac\\
0&\dfrac&\dfrac&\mid&-\dfrac
\end
\]現在到了第 \(2\) 列,未處理過的是 \(2,3\) 行,選最大的 \(\dfrac\) 為主元。
將第 \(3\) 行與第 \(2\) 行交換
\[\begin
4&1&-1&\mid&5\\
0&\dfrac&\dfrac&\mid&-\dfrac\\
0&-\dfrac&\dfrac&\mid&-\dfrac
\end
\]消元得
\[\begin
4&0&-\dfrac&\mid&\dfrac\\
0&\dfrac&\dfrac&\mid&-\dfrac\\
0&0&4&\mid&-4
\end
\]第 \(3\) 列,未處理過的是第 \(3\) 行,選 \(4\) 作主元。
\[\begin
4&0&0&\mid&4\\
0&\dfrac&0&\mid&0\\
0&0&4&\mid&-4
\end
\]這樣就把原來的矩陣通過初等變換,使得係數矩陣只有主對角線位置的元素非零,即乙個對角矩陣。
上面那個矩陣的意思是
\[\begin
4x=4\\
\dfracy=0\\
4z=-4
\end
\]所以再把係數除過去就得到
\[\begin
x=1\\
y=0\\
z=-1
\end
\]請自行檢驗。
時間複雜度為 \(\mathcal(n^3)\)。
當然方程還可能是無解或無窮多解。
考慮乙個一元一次方程 \(ax=b\) 的解的情況:
無解:\(a=0,b\ne0\);
無窮多解:\(a=b=0\);
唯一解:\(a\ne0\)。
所以當發現某一列的主元為 \(0\) 時,因為主元是最大的,所以意味著這一列全都是 \(0\),那麼要麼無解,要麼有無窮多解。
p3389 【模板】高斯消元法
\(\text\)
#include #include #include typedef double db;
using namespace std;
const int maxn = 105;
int n;
db a[maxn][maxn];
bool gauss_jordan()
} if (mx != i)
if (!a[i][i])
for (int j = 1; j <= n; j++)
}} }
return true;
}int main()
} if (gauss_jordan()) }
else
return 0;
}
關於判斷無解和無窮多解
p2455 [sdoi2006]線性方程組
這下要具體到到底是無解還是無窮多解了。
這就是高斯-約旦的乙個缺點:相比於普通高斯,它更難判斷無解和無窮多解。
但是也是可以處理的。
具體地,我們用 \(r\) 來記錄當前行,如果主元為 \(0\),那麼 \(\operatorname\) 到下一列,但 \(r\) 不變;否則消元後令 \(r\gets r+1\)。
遍歷完所有列後:
\(\text\)
#include #include #include typedef double db;
using namespace std;
const int maxn = 55;
int n;
db a[maxn][maxn], ans[maxn];
int gauss_jordan()
} if (mx != r)
if (!a[r][i])
for (int j = 1; j <= n; j++)
}} r++;
} if (--r < n)
}return 0;
} for (int i = 1; i <= n; i++) }
return 1;
}int main()
} int res = gauss_jordan();
if (res != 1)
else }
return 0;
}
高斯 約旦消元法
高斯 約旦消元法 此演算法是基於高斯消元的基礎上改進而成的,唯一不同之處是多進行了幾次矩陣變換使得化為行最簡型矩陣。相比於高斯消元法此方法效率較低,但是不需要回帶求解 此演算法的過程大概為 首先確定每個a i i a i i a i i 不為0 00 如果為0 00就和下面的行替換 接著將每個a i...
高斯 約旦消元法
學了將近兩個晚上。突然看懂時感覺自己是個 寫個部落格記一下吧。模板 洛谷p3389 模板 高斯消元法 有 n 個形如 a 1x 1 a 2x 2 cdots a nx n b 的方程。解方程組。有唯一解則將其求出,否則輸出no solution。把方程組用矩陣形式寫出來 left begin a a...
數學 高斯消元法
struct matrix void show 列主元gaussjordan消元法 int gaussjordan if abs a pivot col eps pos col row if pivot row 列主元置1 for int j m 1 j col j a row j a row co...