• 高斯若尔当消元法


    算法内容:

    该算法主要用于求解线性方程组的解,其原理是,将增广矩阵化成行最简形矩阵,最终能求出方程是否有解、有解时自由元的个数和非自由元的解。

    ///
    ///                            _ooOoo_
    ///                           o8888888o
    ///                           88" . "88
    ///                           (| -_- |)
    ///                           O  =  /O
    ///                        ____/`---'\____
    ///                      .'  \|     |//  `.
    ///                     /  \|||  :  |||//  
    ///                    /  _||||| -:- |||||-  
    ///                    |   | \  -  /// |   |
    ///                    | \_|  ''---/''  |   |
    ///                      .-\__  `-`  ___/-. /
    ///                  ___`. .'  /--.--  `. . __
    ///               ."" '<  `.___\_<|>_/___.'  >'"".
    ///              | | :  `- \`.;` _ /`;.`/ - ` : | |
    ///                 `-.   \_ __ /__ _/   .-` /  /
    ///         ======`-.____`-.___\_____/___.-`____.-'======
    ///                            `=---='
    ///        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ///                      Buddha Bless, No Bug !
    ///
    #include <iostream>
    #include <string>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #define eps 1e-9
    using namespace std;
    const int MAXN = 220;
    double a[MAXN][MAXN], x[MAXN];///方程左边的矩阵和等于等式右边的值,求解之后X存的就是结果
    int equ, var;///(方程数)和(未知数个数)
    /*
    返回-1表示一个解,0表示无解,其余的数表示有K个自由元
    */
    int Gauss()
    {
        int i, j, k, col, max_r;
        for (k = 0, col = 0; k < equ && col < var; k++, col++)
        {
            max_r = k;
            for (i = k + 1; i < equ; i++)///逐层寻找绝对值比第(k, k)个数大的数,便于后面化成行最简型
            {
                if (fabs(a[i][col]) > fabs(a[max_r][col]))///逐层寻找绝对值比第(k, k)个数大的数,便于后面化成行最简型
                {
                    max_r = i;
                }
            }
            if (abs(a[max_r][col]) < eps)
            {
                continue;
            }
            if (k != max_r)///如果最大的数所在行不与K同行,就进行交换,方便后面的行减去他,然后转换成行最简型
            {
                for (j = col; j < var; j++)///进行交换
                {
                    swap(a[k][j], a[max_r][j]);
                }
                swap(x[k], x[max_r]);
            }
            x[k] /= a[k][col];
            for (j = col + 1; j < var; j++)///使(k,col)元素在k行以后的元素都除以他,而他自己变成1
            {
                a[k][j] /= a[k][col];///使a[k][col] = 1,使这行逐渐变成行最简形矩阵
            }
            a[k][col] = 1;
            for (i = 0; i < equ; i++)
            {
                if (i != k)
                {
                    x[i] -= x[k] * a[i][k];///x[i] 减去 (第k行的x[k]与a[i][k]的乘积),与后面的a[i][j] -= a[k][j] * a[i][col]合在一起就是每一行减去第K行
                    for (j = col + 1; j < var; j++)
                    {
                        a[i][j] -= a[k][j] * a[i][col];///使(其他所有行)减去(第k行)
                    }
                    a[i][col] = 0;
                }
            }
        }
        for (i = equ - 1; i >= 0; i--)///
        {
            bool bul = 1;
            for (j = var - 1; j >= 0; j--)
            {
                if (abs(a[i][j]) > eps)///如果有解(R(a) = R(a, x))
                {
                    bul = 0;
                }
            }
            if (bul && abs(x[i]) > eps)///如果无解(R(a)<R(a, x))
            {
                return 0;
            }
        }
        int free_num = var;
        for (i = equ - 1; i >= 0; i--)///
        {
            for (j = var - 1; j >= 0; j--)
            {
                if (abs(a[i][j]) > eps)
                {
                    free_num--;///计算自由元个数
                    break;
                }
            }
        }
        if (free_num == 0)
        {
            return -1;
        }
        return var - free_num;
    }
    int main()
    {
        int n, m;
        while (scanf("%d%d", &equ, &var) != EOF)
        {
            for (int i = 0; i < equ; i++)
            {
                for (int j = 0; j < var; j++)
                {
                    cin >> a[i][j];
                }
                cin >> x[i];///存的是方程的结果,也就是增广矩阵的b[]
                a[i][var] = i + 1;///存这个行的序号
            }
            cout << Gauss() << endl;
            for (int i = 0; i < equ; i++)
            {
                for (int j = 0; j < var; j++)
                {
                    printf("%5.2f ", a[i][j]);///输出矩阵变换后的每个数
                }
                cout << endl;
            }
            for (int i = 0; i < var; i++)
            {
                printf("%d : %.2f
    ", i + 1, x[i]);///x[i]此时存的是未知数的解
            }
        }
        return 0;
    }
  • 相关阅读:
    mysql_day04
    四则运算_EX
    第二阶段站立会议9
    对搜狗输入法的评价
    找水王
    第二阶段站立会议8
    第二阶段站立会议7
    第二次站立冲刺会议6
    第二阶段站立冲刺会议5
    第二阶段站立冲刺会议4
  • 原文地址:https://www.cnblogs.com/RootVount/p/11274090.html
Copyright © 2020-2023  润新知