高斯消元:列主消元法

博客介绍了列主消元法,它是为控制舍入误差提出的算法。基本思想是在第k步消元时,从第k列akk及其以下元素中选绝对值最大元素,通过行变换换到主元素akk位置再消元,还给出了一个方程组示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是列主消元

(注: akk代表第k行第k列的权值, 以下摘自百度百科:列主消元法
列主元素消去法是为控制舍入误差而提出来的一种算法,列主元素消去法计算基本上能控制舍入误差的影响,其基本思想是:在进行第 k(k=1,2,…,n-1)步消元时,从第k列的 akk及其以下的各元素中选取绝对值最大的元素,然后通过行变换将它交换到主元素akk的位置上,再进行消元。
在这里插入图片描述BZ:好吧!其实思路的挺清晰的,那么,我们就开始放代码了:::

//#include<bits/stdc++.h>
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<stack>
#include<queue>			//stack的头文件
using namespace std ;
typedef long long ll;
#define MAXN 501
#define INF 0x3f3f3f3f
#define MALL (BiTnode *)malloc(sizeof(BiTnode));

double a[MAXN][MAXN+1];
double b[MAXN][MAXN+1];
double x[MAXN];
void init(int n)                            //输入n阶矩阵,包含输入增广矩阵,即[n*(n-1)]
{
    memset(a, 0, sizeof(a));
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n+1; ++j)
        {
            scanf("%lf", &a[i][j]);
            b[i][j] = a[i][j];
        }
}

int gaosi(int n)
{
    for(int i=1; i<n; ++i)
    {
        if(!b[i][i])
            return 0;
        for(int j=i+1; j<=n+1; ++j)
        {
            double ans = 1.0*b[j][i]/b[i][i];
            for(int k=i; k<=n+1; ++k)
                b[j][k] = b[j][k] - 1.0*ans*b[i][k];
        }
    }
     if(!b[n][n])
        return 0;
    return 1;
}

int gaosi_liezhu(int n)                      //列主消元(上三角)
{
    for(int i=1; i<n; ++i)
    {
        double tem = fabs(a[i][i]);          //tem标记第i行第i列以下第x(x >= i)列中的绝对值最大的数
        int cnt = i;                         //cnt标记第几行,用于行交换。

        for(int j=i+1; j<=n; ++j)
        {
            if(fabs(a[j][i]) > tem)
            {
                tem = fabs(a[j][i]);
                cnt = j;
            }
        }
        for(int j=i; j<=n+1; ++j)           //行交换
        {
            double p = a[i][j];
            a[i][j] = a[cnt][j];
            a[cnt][j] = p;
        }

        if(!a[i][i])                        //正常的高斯消元
            return 0;
        for(int j=i+1; j<=n; ++j)
        {
            double ans = 1.0*a[j][i]/a[i][i];
            for(int k=i; k<=n+1; ++k)
                a[j][k] = a[j][k] - 1.0*ans*a[i][k];
        }
    }
     if(!a[n][n])
        return 0;
    return 1;
}

void print_a(int n)           //输出消元后的上三角矩阵
{
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n+1; ++j)
            if(a[i][j] < 1e-5 && a[i][j] > -1e-5)
                printf("0.0 ");
            else
                printf("%.1f ", a[i][j]);
        cout << '\n';

    }
}

void print_b(int n)           //输出消元后的上三角矩阵
{
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n+1; ++j)
            if(b[i][j] < 1e-5 && b[i][j] > -1e-5)
                printf("0.0 ");
            else
                printf("%.1f ", b[i][j]);
        cout << '\n';
    }
}

void jie_a(int n)                //回代方程求出方程组的解;
{
    memset(x, 0, sizeof(x));
    x[n] = 1.0*a[n][n+1]/a[n][n];
    for(int i=n-1; i>0; --i)
    {
        double ans=0.0;
        for(int j=i+1; j<=n; ++j)
            ans+=1.0*a[i][j]*x[j];
        x[i] = (a[i][n+1] - ans)*1.0/a[i][i];
    }

    for(int i=1; i<=n; ++i)
        if(x[i] < 1e-5 && x[i] > -1e-5)
            printf("x%d = 0.0\n", i);
        else
            printf("x%d = %.1f\n", i, x[i]);
}

void jie_b(int n)                //回代方程求出方程组的解;
{
    memset(x, 0, sizeof(x));
    x[n] = 1.0*b[n][n+1]/b[n][n];
    for(int i=n-1; i>0; --i)
    {
        double ans=0.0;
        for(int j=i+1; j<=n; ++j)
            ans+=1.0*b[i][j]*x[j];
        x[i] = (b[i][n+1] - ans)*1.0/b[i][i];
    }

    for(int i=1; i<=n; ++i)
        if(x[i] < 1e-5 && x[i] > -1e-5)
            printf("x%d = 0.0\n", i);

        else
            printf("x%d = %.1f\n", i, x[i]);
}
int main()
{
    double a[MAXN][MAXN+1];
    cout << "请输入方程的阶数n:";
    int n;
    cin >> n;
    cout << "请输入n阶方程的增广矩阵:" << '\n';
    init(n);
    cout << "\n-------高斯消元后的结果为------" << '\n';
    int j = gaosi(n);
    if(j)
    {
        print_b(n);
        cout << "----利用该矩阵回代后解出其解为----" << '\n';
        jie_b(n);
    }
    else
        cout << "该方程组顺序消元后无解!" << '\n';
    cout << "\n-------列主消元后的结果为------" << '\n';
    int i = gaosi_liezhu(n);
    if(i)
    {
        print_a(n);
        cout << "----利用该矩阵回代后解出其解为----" << '\n';
        jie_a(n);
    }
    else
        cout << "该方程组列主消元后无解!" << '\n';
    return 0;
}




##### 样例检测:

方程组:
x1 - x2 - x3 = 2,
2 * x1 - x2 - 3 * x3 = 1,
3 * x1 + 2 * x2 - 5 * x3 = 0.

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值