线性方程组的直接解法——Gauss消去法

考虑线性方程组

Ax=b

其中,A=(aij)n×nb=[b1,b2,,bn]T。在线性代数的课程中,我们已经学习过Gauss消元法,具体操作是将矩阵A转化为“阶梯型”矩阵。为方便起见,本文仅仅讨论系数矩阵非奇异的方程组,此时,目标是将矩阵A转化为上三角矩阵,再执行回代过程,即可给出方程组的解。本文将给出在计算机上的具体操作及实例代码。

一、基本Gauss消去法

我们仅仅讨论对矩阵第一列的操作,剩余的操作可以以此类推,因而不再赘述。
在执行Gauss消去法时,我们将第一列对角元以下的元素全部变为零。记第一列消元操作后的增广矩阵为[A(1),b(1)],容易知道

[A(1),b(1)]=[a11a22a1nb10a22(1)a2n(1)b2(1)0an2(1)ann(1)bn(1)]

其中

aij(1)=aijai1a11a1jj=2,,n

ai1(1)=0

bi(1)=biai1a11b1

观察到重复出现的结构ai1a11,我们记它为li1,称为消元因子,并将它存储在原来ai1的位置。在计算的过程中,先计算消元因子并存储在相应位置,再执行后续的算法。
对于后续部分的运算,在第k步,只要对矩阵A(k1)(k:n,k:n)执行相同操作即可。

二、列主元Gauss消去法

在执行Gauss消元法的过程中,如果akk(k1)相对于其他元素绝对值较小,则会产生较大的舍入误差,影响计算精度,为此,我们引入了列主元Gauss消去法,基于交换矩阵的行不影响线性方程组的解。
记执行完k-1步消元后的增广矩阵为[A(k1),b(k1)]。考虑第k列对角元及其以下的部分。选择绝对值最大的元所在行,与当前行执行行交换,再进行Gauss消元法。

三、计算实例

用列主元Gauss消去法解以下线性方程组:

{0.5x1+1.1x2+3.1x3=6,2x1+4.5x2+3.6x3=0.02,5x1+0.96x2+6.5x3=0.96.

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    double A_Extended[3][4]={0.5,1.1,3.1,6,2,4.5,3.6,0.02,5,0.96,6.5,0.96};
    double X_solution[3];
    for (int i=0;i<=2;i++)
    {
        int n=i;
        for (int p=i+1;p<=2;p++)
        {
            if (fabs(A_Extended[p][i])>fabs(A_Extended[n][i]))
            {
                n=p;
            }
        }

        for (int p=i;p<=2+1;p++)
        {
            double k=A_Extended[n][p];
            A_Extended[n][p]=A_Extended[i][p];
            A_Extended[i][p]=k;
        }

        for (int p=i+1;p<=2;p++)
        {
            A_Extended[p][i]=-A_Extended[p][i]/A_Extended[i][i];
            for (int pco=i+1;pco<=2+1;pco++)
            {
                A_Extended[p][pco]=A_Extended[p][pco]+A_Extended[p][i]*A_Extended[i][pco];
            }
        }
    }
    X_solution[2]=A_Extended[2][3]/A_Extended[2][2];
    for (int i=1;i>=0;i--)
    {
        double sum=0;
        for (int k=2;k>i;k--)
        {
            sum=sum+A_Extended[i][k]*X_solution[k];
        }
        X_solution[i]=(A_Extended[i][3]-sum)/A_Extended[i][i];
    }

    cout<<X_solution[0]<<" "<<X_solution[1]<<" "<<X_solution[2]<<endl;
    return 0; 
}
posted @   WeShiko的博客  阅读(1067)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示