1.概述
高斯消元法(Gaussian elimination)是求解线性方阵组的一种算法,它也可用来求矩阵的秩,以及求可逆方阵的逆矩阵。它通过逐步消除未知数来将原始线性系统转化为另一个更简单的等价的系统。它的实质是通过初等行变化(Elementary row operations),将线性方程组的增广矩阵转化为行阶梯矩阵(row echelon form).
2.原理
已知线性方程组:
首先,要将以下的等式中的消除,然后再将以下的等式中的消除。这样可使整个方程组变成一个三角形似的格式。之后再将已得出的答案一个个地代入已被简化的等式中的未知数中,就可求出其余的答案了。所以我们可以用初等行变换把增广矩阵转换为行阶梯阵,然后回代求出方程的解。
3.求解过程
已知线性方程组:
①.构造增广矩阵,即系数矩阵A增加上常数向量b(A|b).
②.通过以交换行、某行乘以非负常数和两行相加这三种初等变化将原系统转化为更简单的三角形式(triangular form)
注:这里的初等变化可以通过系数矩阵A乘上初等矩阵E来实现.
③.从而得到简化的三角方阵组,这样就容易解了.
这样就完成了整个算法的初步,一个三角形的格式(指:变量的格式而言,上例中的变量各为3,2,1个)出现了。
④.这时就可以使用向后替换算法(Algorithm for Back Substitution)求解得.
这一步就是由尾至头地将已知的答案代入其他等式中的未知数。第一个答案就是:
然后就可以将代入中,立即就可得出第二个答案:
之后,将和代入之中,最后一个答案就出来了:
就是这样,这个方程组就被高斯消元法解决了。
4.总结
总结上面过程,高斯消元法其实就是下面非常简单的过程:
原线性方程组前向替换算法求解(对于上三角形式,采用后向替换算法).
代码
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 110;
const double eps = 1e-6;
int n;
double a[N][N];
void out() {
for (int i = 0; i < n; i++) {
for (int j = 0; j <= n; j++) {
printf("%10.2lf", a[i][j]);
}
}
puts(" ");
}
int gauss() {
int c, r;
for (c = 0, r = 0; c < n; c++) {
int t = r;
for (int i = r; i < n; i++) {
if (fabs(a[i][c]) > fabs(a[t][c])) {
t = i;
}
}
if (fabs(a[t][c]) < eps) continue;
for (int i = c; i <= n; i++) swap(a[t][i], a[r][i]);
for (int i = n; i >= c; i--)a[r][i] /= a[r][c];
for (int i = r + 1; i < n; i++) {
if (fabs(a[i][c]) > eps) {
for (int j = n; j >= c; j--) {
a[i][j] -= a[r][j] * a[i][c];
}
}
}
r++;
}
if (r < n) {
for (int i = r; i < n; i++) {
if (fabs(a[i][n]) > eps)
return 2;//无解
}
return 1;//有无穷多组解
}
for (int i = n - 1; i >= 0; i--) {
for (int j = i + 1; j < n; j++) {
a[i][n] -= a[i][j] * a[j][n];
}
}
return 0;//有唯一解
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n+1; j++) {
cin >> a[i][j];
}
}
int t = gauss();
if (t == 0) {
for (int i = 0; i < n; i++)printf("%.2lf\n", a[i][n]);
}
else if (t == 1)puts("Infinite group solutions");
else puts("No solution");
return 0;
}