高斯(Gauss)列主元消去法:对给定的 n n n阶线性方程组 A x = b Ax = b Ax=b,首先进行列主元消元过程,然后进行回代过程,最后得到解或确定该线性方程组是奇异的。
如果系数矩阵的元素按绝对值在数量级方面相差很大,那么,在进行列主元消元过程前,先把系数矩阵的元素进行行平衡:系数矩阵的每行元素和相应的右端向量元素同除以该行元素绝对值最大的元素。这就是所谓的平衡技术。然后再进行列主元消元过程。
如果真正进行运算去确定相对主元,则称为显式相对Gauss列主元消去法;如果不进行运算,也能确定相对主元,则称为隐式相对Gauss列主元消去法。
显式相对Gauss列主元消去法:对给定的 n n n阶线性方程组 A x = b Ax = b Ax=b,首先进行列主元消元过程,在消元过程中利用显式平衡技术,然后进行回代过程,最后得到解或确定该线性方程组是奇异的。
隐式相对Gauss列主元消去法:对给定的 n n n阶线性方程组 A x = b Ax = b Ax=b,首先进行列主元消元过程,在消元过程中利用隐式平衡技术,然后进行回代过程,最后得到解或确定该线性方程组是奇异的。
Gauss列主元消去法
1对 k = 1 , 2 , ⋯ , n − 1 k = 1,2,\cdots,n - 1 k=1,2,⋯,n−1,做1.1—1.3,消元过程
1.1 寻找最小的正整数 p p p, k ≤ p ≤ n k \leq p \leq n k≤p≤n和 ∣ a pk ∣ = max k ≤ j ≤ n ∣ a jk ∣ \left| a_{\text{pk}} \right| = \max_{k \leq j \leq n}\left| a_{\text{jk}} \right| ∣apk∣=maxk≤j≤n∣ajk∣。如果 a pk = 0 a_{\text{pk}} = 0 apk=0,输出奇异标志,停机;
1.2 如果 p ≠ k p \neq k p=k,那么交换 p , k p,k p,k两行;
1.3 对 i = k + 1 , ⋯ , n i = k + 1,\cdots,n i=k+1,⋯,n , 记 ,记 ,记 m ik = a ik / a kk m_{\text{ik}} = a_{\text{ik}}/a_{\text{kk}} mik=aik/akk$,计算
{ a ij = a ij − a kj m ik i = k + 1 , ⋯ , n j = k + 1 , ⋯ , n b i = b i − b k m ik i = k + 1 , ⋯ , n \left\{ \begin{matrix} \ a_{\text{ij}} = a_{\text{ij}} - a_{\text{kj}}m_{\text{ik}} \\ \ i = k + 1,\cdots,n \\ \ j = k + 1,\cdots,n \\ \ b_{i} = b_{i} - b_{k}m_{\text{ik}} \\ \ i = k + 1,\cdots,n \\ \end{matrix} \right.\ ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧ aij=aij−akjmik i=k+1,⋯,n j=k+1,⋯,n bi=bi−bkmik i=k+1,⋯,n
如果 a nn = 0 a_{\text{nn}} = 0 ann=0输出奇异标志,停机;
置 x n = b n / a nn x_{n} = b_{n}/a_{\text{nn}} xn=bn/ann,回代过程
对 k = n − 1 , ⋯ , 2 , 1 k = n - 1,\cdots,2,1 k=n−1,⋯,2,1,置 x k = ( b k − ∑ j = k + 1 n a kj x j ) / a kk x_{k} = (b_{k} - \sum_{j = k + 1}^{n}{a_{\text{kj}}x_{j}})/a_{\text{kk}} xk=(bk−∑j=k+1nakjxj)/akk
#include
#include
#include
using namespace std;
#define N 10
int n;
double a[N][N], b[N], x[N];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) scanf("%lf", &a[i][j]);
for (int i = 1; i <= n; i++) scanf("%lf", &b[i]);
for (int k = 1; k < n; k++) {
int p = k;
double maxabs = fabs(a[k][k]);
for (int j = k + 1; j <= n; j++)
if (fabs(a[j][k]) - maxabs > 0) {
p = j;
maxabs = fabs(a[j][k]);
}
if (a[p][k] == 0) {
printf("Singular");
return 0;
}
if (p != k) {
double tmp;
for (int j = 1; j <= n; j++) {
tmp = a[p][j];
a[p][j] = a[k][j];
a[k][j] = tmp;
}
tmp = b[p];
b[p] = b[k];
b[k] = tmp;
}
for (int i = k + 1; i <= n; i++) {
double m_ik = a[i][k] / a[k][k];
for (int j = k + 1; j <= n; j++) a[i][j] -= a[k][j] * m_ik;
b[i] -= b[k] * m_ik;
}
}
if (a[n][n] == 0) {
printf("Singular");
return 0;
}
x[n] = b[n] / a[n][n];
for (int k = n - 1; k >= 1; k--) {
double sigma = 0.0;
for (int j = k + 1; j <= n; j++) sigma += a[k][j] * x[j];
x[k] = (b[k] - sigma) / a[k][k];
}
for (int i = 1; i <= n; i++) printf("%lf\t", x[i]);
return 0;
}