zoukankan      html  css  js  c++  java
  • 【模板】高斯(约旦)消元

    高斯消元

    ​ 运用增广矩阵的三种初等行变换,求解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
    ", 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
    ", a[i][n+1]/a[i][i]);
        else puts("No Solution");
        return 0;
    }
    
  • 相关阅读:
    腾讯Techo开发者大会PPT分享
    构建三维一体立体化监控,看这一篇就够了!
    ACOUG 联合创始人盖国强:万象更新,数据库技术和生态的发展演进
    全局配置项set_global_options 支持的opts
    InitOpts:初始化配置项:
    数据结构第四章树和森林,期末不挂科指南,第7篇
    Netflix:当你按下“播放”的时候发生了什么?
    Netflix:当你按下“播放”的时候发生了什么?
    搭建vsftpd文件服务器并创建虚拟用户
    搭建vsftpd文件服务器并创建虚拟用户
  • 原文地址:https://www.cnblogs.com/TY02/p/12242418.html
Copyright © 2011-2022 走看看