【模板】高斯(约旦)消元

高斯消元

​ 运用增广矩阵的三种初等行变换,求解n元线性方程组的算法。如果先消得阶梯形矩阵(向前步骤),再通过回代(向后步骤)解出简化阶梯形矩阵,称为高斯消元法;若直接以含有主元的行消去其余方程中的该项,称为约旦-高斯消元法。

​ 两种方法的时间复杂度相同,区别在于约旦消元没有回代过程,代码简单,而高斯消元实际执行次数较少,效率更快。

代码:

//高斯消元
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define maxn 110
const double eps(1e-7);
using namespace std;
double A[maxn][maxn];
int n;
void print() {
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= n + 1; ++j) cout << A[i][j] << " ";
		cout << endl;
	}
	cout << endl;
}
void Gause() {
    for (int k = 1; k <= n; ++k) {
        int mxp = k;
        for (int i = k + 1; i <= n; ++i) //确认系数 
            if (abs(A[i][k]) > abs(A[mxp][k])) mxp = i;
        if (abs(A[mxp][k]) < eps) 
            puts("No Solution"), exit(0);
        for (int i = 1; i <= n + 1; ++i) //对换 
            swap(A[mxp][i], A[k][i]);
        for (int i = k + 1; i <= n; ++i) {//消元 
            double p = A[i][k] / A[k][k];
            for (int j = 1; j <= n + 1; ++j)
                A[i][j] -= p * A[k][j];
        }
    }
    for (int k = n; k; --k) {
        if (abs(A[k][k]) < eps)
            puts("No Solution"), exit(0);
        A[k][n+1] /= A[k][k];//x_k得解
        for (int i = 1; i < k; ++i) {//回代 
            A[i][n+1] -= A[i][k] * A[k][n+1];
        }
    }
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n + 1; ++j) cin >> A[i][j];
    Gause();
    for (int i = 1; i <= n; ++i) printf("%.2lf\n", A[i][n+1]);
    return 0;
}
//约旦消元
#include <iostream>
#include <algorithm>
#include <cstdio>
const int maxn(110);
const double eps(1e-7);
using namespace std;
double a[maxn][maxn];
int n;
bool Jordan() {
    for (int k = 1; k <= n; ++k) {
        int mxp = k;
        for (int i = k + 1; i <= n; ++i)//选取绝对值最大的行作为该主元的代表行,称为部分主元法
            if (abs(a[i][k]) > abs(a[mxp][k])) mxp = i;
        if (abs(a[mxp][k]) < eps) return false;
        for (int i = 1; i <= n + 1; ++i) swap(a[k][i], a[mxp][i]);
        for (int i = 1; i <= n; ++i) {//消去每个方程中的该项
            if (i == k) continue;
            double t = a[i][k] / a[k][k];
            a[i][k] = 0;
            for (int j = k + 1; j <= n + 1; ++j)
                a[i][j] -= a[k][j] * t;
        }
    }
    for (int i = 1; i <= n; ++i) {
    	for (int j = 1; j <= n + 1; ++j) cout << a[i][j] << " ";
    	cout << endl;
    }
    return true;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) 
        for (int j = 1; j <= n + 1; ++j) scanf("%lf", &a[i][j]);
    if (Jordan())
        for (int i = 1; i <= n; ++i) printf("%.2lf\n", a[i][n+1]/a[i][i]);
    else puts("No Solution");
    return 0;
}
posted @ 2020-01-30 12:00  onyYuan  阅读(266)  评论(0编辑  收藏  举报