用列主元素的Gauss消元法求解线性方程组

例如:

\left\{\begin{matrix} &x_{1}+&2x_{2}-&x_{3}=3 \\ &x_{1}-&x_{2}+&5x_{3}=0 \\ &4x_{1}+&x_{2}-&2x_{3}=2 \end{matrix}\right.

即:

\begin{pmatrix} &1 &2 & -3&3\\ &1 &-1 &5 &0\\ &4 &1 &-2 &2 \end{pmatrix}

利用列主元的Gauss消去法求解x

#include<iostream>
#include<cstdio>
#include<cmath>
#include<iomanip>
using namespace std;
#define error 0.00000001
#define maxn 50

int    n;//规模nXn
double a[maxn][maxn];//系数矩阵
double b[maxn];//b矩阵
double m[maxn][maxn];//中间变量矩阵
double x[maxn];//最终解
int    H=1;//扩大H被结算(优化)
/*
读取数据
*/
void read()
{
    cout<<"请输入系数矩阵规模n= ";
    cin>>n;
    cout<<"请输入系数矩阵A:"<<endl;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
        {
            cin>>a[i][j];
            a[i][j]*=H;
        }

    cout<<"请输入增广矩阵b:\n";

    for(int i=1; i<=n; i++)
    {
        cin>>b[i];
        b[i]*=H;
    }
}

/*
中间矩阵输出
参数:消元次数
*/
void PrintProc(int cases)
{
    printf("--------第%d次消元结果如下:\n",cases);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            cout<<setw(10)<<a[i][j]<<' ';
        }
        cout<<setw(10)<<b[i]<<'\n';
    }
    cout<<endl;
}

/*
显示结果
*/
void Print()
{
    cout<<"结果为:\n";
    for(int i=1; i<=n; i++)
    {
        printf("x[%d]=  %lf\n",i,x[i]);
    }
}

/*列主消元*/
void LieZhuXiaoYuan()
{
    for(int k=1; k<n; k++)
    {
        //选主元[这一列的绝对值最大值]
        double ab_max=-1;
        int       max_ik;//主元行号
        for(int i=k; i<=n; i++)
        {
            if(abs(a[i][k])>ab_max)
            {
                ab_max=abs(a[i][k]);
                max_ik=i;
            }
        }
        //交换行处理[先判断是否为0矩阵]
        if(ab_max<error) //0矩阵情况
        {
            cout<<"det A=0\n";
            break;
        }
        else if(max_ik!=k)  //是否是当前行,不是交换
        {
            double temp;
            for(int j=1; j<=n; j++)
            {
                temp=a[max_ik][j];
                a[max_ik][j]=a[k][j];
                a[k][j]=temp;
            }
            temp=b[max_ik];
            b[max_ik]=b[k];
            b[k]=temp;
        }
        //消元计算
        for(int i=k+1; i<=n; i++)
        {
            a[i][k]/=a[k][k];//这里需要注意,与笔算时的思路不同,需要在这“保存”着比值,以便之后的编程使用,而不像笔算时除主元之外的元素全部消为0

            for(int j=k+1; j<=n; j++)
            {
                a[i][j]-=a[i][k]*a[k][j];
            }
            b[i]-=a[i][k]*b[k];
        }
        PrintProc(k);//输出中间计算过程
        if(k<n-1)continue;
        else
        {
            if(abs(a[n][n])<error)
            {
                cout<<"det A=0\n";
                break;
            }
            else  //回代求解
            {
                x[n]=b[n]/a[n][n];
                for(int i=n-1; i>0; i--)
                {
                    x[i]=b[i];
                    for(int j=i+1; j<=n; j++)
                        x[i]-=a[i][j]*x[j];//全部移到等式右边
                    x[i]/=a[i][i];//除以Xi的系数,得到最终解
                }
                //输出结果
                Print();
            }
        }
    }
}

/*
主函数
*/
int main()
{
    while(1)
    {
        read();
        LieZhuXiaoYuan();
        //ShunXuXiaoYuan();
    }
    return 0;
}

输出结果:

发布了51 篇原创文章 · 获赞 7 · 访问量 7474

猜你喜欢

转载自blog.csdn.net/Jason6620/article/details/90319604