首页 > 编程语言 >Gauss列主元素消去法-C++【可直接复制粘贴/欢迎评论点赞】

Gauss列主元素消去法-C++【可直接复制粘贴/欢迎评论点赞】

时间:2024-09-13 12:21:20浏览次数:11  
标签:++ double 矩阵 Gauss 主元 复制粘贴 C++ 消去法

Gauss列主元素消去法(也称为列主元Gauss消去法)是Gauss消去法的一种改进版本,主要用于求解线性方程组。在C++中实现时,它具有一些显著的优点和缺点,并且有着深厚的数学和计算背景。

优点

  1. 提高数值稳定性:列主元Gauss消去法通过在每一列中选择绝对值最大的元素作为主元,从而避免了在消元过程中使用过小或接近零的主元,这有助于提高计算的数值稳定性和精度。
  2. 减少误差累积:由于选择了较大的主元进行消元,该方法能够减少因舍入误差导致的误差累积,特别是在处理大规模或条件数较大的线性方程组时尤为重要。
  3. 广泛适用性:列主元Gauss消去法不仅适用于求解线性方程组,还可以应用于求解矩阵的逆、求解最小二乘问题等,具有广泛的应用领域。
  4. 易于实现:尽管算法相对复杂,但C++作为一种高效的编程语言,能够很好地支持列主元Gauss消去法的实现,使得该方法在实际应用中易于部署和使用。

缺点

  1. 时间复杂度较高:相比于简单的Gauss消去法,列主元Gauss消去法需要额外的步骤来寻找每一列的主元并进行行交换,这增加了算法的时间复杂度。特别是在处理大型稀疏矩阵时,这种增加可能更加显著。
  2. 对矩阵排列有要求:列主元Gauss消去法的性能受到矩阵中元素排列的影响。在某些特殊情况下,如果矩阵的元素排列不利于主元的选择,可能会导致算法的效率降低。
  3. 数值稳定性并非绝对:虽然列主元Gauss消去法提高了数值稳定性,但在某些极端情况下(如矩阵接近奇异),仍然可能出现数值不稳定的问题。

背景

Gauss列主元素消去法是基于Gauss消去法的一种改进。Gauss消去法是一种经典的线性方程组求解方法,它通过将线性方程组转换为增广矩阵,并通过一系列的行变换将矩阵转换为上三角形或对角形矩阵,从而简化求解过程。然而,传统的Gauss消去法在处理某些特定类型的线性方程组时,可能会因为主元过小而导致数值不稳定。为了克服这一缺点,人们提出了列主元Gauss消去法,通过在每一列中选择绝对值最大的元素作为主元,以提高算法的数值稳定性和精度。

在C++中实现Gauss列主元素消去法时,需要遵循算法的基本原理和步骤,包括选择主元、进行行交换、执行消元操作以及最后通过回代求解出未知数的值。此外,还需要注意数值精度、输入验证等问题,以确保算法的正确性和稳定性。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;


void SolverEqGauss(double **A, double *b, int n, double *x);
//其中A和b为系数矩阵,n为矩阵阶数,x为待求解变量,eps为精度。
int main()
{
    int i, n;
	double **A, *b, *x;
	//输入维数
	cin >> n;
	A = new double *[n];
	b = new double[n];
	x = new double[n];
	for (i = 0; i < n; i++)
	{
		A[i] = new double[n];
	}
	//输入系数矩阵和向量
    for (i = 0; i < n; i++) 
	{
        for (int j = 0; j < n; j++)
		{
            cin >> A[i][j];
        }
    }
    for (int i = 0; i < n; i++) 
	{
        cin >> b[i];
    }

	//计算
	SolverEqGauss(A, b, n, x);
	//输出
	for (i = 0; i < n; i++)
	{
		cout << fixed << setprecision(5) << x[i] <<" ";
	}
	delete[]b;//释放内存
	delete[]x;
	for (i = 0; i < n; i++)
	{
		delete[]A[i];
	}
	return 0;
}

 
void SolverEqGauss(double **A, double *b, int n, double *x)  
{  
    int i, j, k, maxRow;  
    double **a = new double *[n];  
    double *btemp = new double[n];  
    double d, temp, maxPivot;  
  
    for (i = 0; i < n; i++)  
    {  
        a[i] = new double[n + 1];  
    }  
  
    // 赋值  
    for (i = 0; i < n; i++)  
    {  
        for (j = 0; j < n; j++)  
        {  
            a[i][j] = A[i][j];  
        }  
        a[i][n] = b[i];  
    }  
  
    for (k = 0; k < n - 1; k++)  
    {  
        // 找列主元最大值  
        maxPivot = fabs(a[k][k]);  
        maxRow = k;  
        for (i = k + 1; i < n; i++)  
        {  
            if (fabs(a[i][k]) > maxPivot)  
            {  
                maxPivot = fabs(a[i][k]);  
                maxRow = i;  
            }  
        }  
        // 如果最大主元为0,则矩阵奇异,无法求解  
        if (maxPivot == 0)  
        {  
            cerr << "The matrix is singular, cannot solve." << endl;  
            exit(EXIT_FAILURE);  
        }  
  
        // 换行  
        if (maxRow != k)  
        {  
            for (j = k; j <= n; j++)  
            {  
                temp = a[k][j];  
                a[k][j] = a[maxRow][j];  
                a[maxRow][j] = temp;  
            }  
        }  
  
        // 消元  
        for (i = k + 1; i < n; i++)  
        {  
            d = a[i][k] / a[k][k];  
            for (j = k + 1; j <= n; j++)  
            {  
                a[i][j] -= d * a[k][j];  
            }  
        }  
    }  
  
    // 回代求解  
    for (i = n - 1; i >= 0; i--)  
    {  
        btemp[i] = a[i][n];  
        for (j = i + 1; j < n; j++)  
        {  
            btemp[i] -= a[i][j] * btemp[j];  
        }  
        btemp[i] /= a[i][i];  
    }  
  
    // 将解赋值给x  
    for (i = 0; i < n; i++)  
    {  
        x[i] = btemp[i];  
    }  
  
    // 释放内存  
    for (i = 0; i < n; i++)  
    {  
        delete[] a[i];  
    }  
    delete[] a;  
    delete[] btemp;  
}

标签:++,double,矩阵,Gauss,主元,复制粘贴,C++,消去法
From: https://blog.csdn.net/ws13563798156/article/details/142207672

相关文章

  • 牛顿插值法-C++【可直接复制粘贴/欢迎评论点赞】
    牛顿插值法是一种基于给定数据点集构造插值多项式的方法,用于近似未知函数的值。该方法通过构造差商表并利用该表逐步构建插值多项式。相较于拉格朗日插值法,牛顿插值法的一个显著优势是,当需要增加插值点时,只需重附上一项即可,无需重新计算所有插值点的值。基本概念牛顿插值法的......
  • 基于matlab的黄金搜索法【开源/可直接复制粘贴】
    黄金搜索法是一种无须函数导数的数值优化方法。它基于黄金分割比例来选择新的搜索区间,以逐步缩小搜索范围并逼近极值点。在每次迭代中,算法会根据当前搜索区间的长度和黄金分割比例来计算两个新的点,并在这两个点处评估函数值。然后,根据这两个点的函数值比较结果,选择包含更优解(......
  • 【C++基础概念理解——std::invoke()函数基础知识】
    std::invoke定义std::invoke是C++17引入的一个标准库函数,用于通用地调用可调用对象(如函数指针、成员函数指针、函数对象、lambda表达式等)。它提供了一种统一的方式来调用这些可调用对象,而不需要关心它们的具体类型。功能std::invoke可以调用以下类型的可调用对象:......
  • C++17新特性探索:拥抱std::optional,让代码更优雅、更安全
    std::optional背景在编程时,我们经常会遇到可能会返回/传递/使用一个确定类型对象的场景。也就是说,这个对象可能有一个确定类型的值也可能没有任何值。因此,我们需要一种方法来模拟类似指针的语义:指针可以通过nullptr来表示没有值。解决方法是定义该对象的同时再定义一个附加的......
  • 分享一些程序员常用的C++知识点
    以下是一些C++中的常用知识点:一、基础语法数据类型基本数据类型:整型(int):用于表示整数,通常占用4个字节(32位系统)。例如:intnum=10;浮点型(float、double):用于表示小数,float精度较低,double精度较高。如floatf=3.14f;(注意f后缀表示float类型),doubled=3.1415926......
  • C++入门基础
    个人主页:Jason_from_China-CSDN博客所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客前言 这一篇章算是C++栏目的语法的第一篇章,主要是为类和对象打下基础,介绍一些C++基本的语法结构这里提醒一下,要是看不懂第一步创建文件的,其实更建议先学习一下C语言,因为C++的......
  • Qt C++设计模式->建造者模式
    建造者模式简介建造者模式(BuilderPattern)是一种创建型设计模式,它通过使用多个简单的对象一步步构建一个复杂对象。建造者模式允许你分步骤创建复杂对象,并且你可以控制每个步骤如何执行。该模式常用于对象的创建过程非常复杂且需要有多个可选参数的场景。建造者模式的应用场......
  • VSCode配置C++环境
    前言VSCode作为一款“宇宙级”的编辑软件,为用户提供了丰富的插件。本文是一片保姆级关于VSCode配置C++环境教程;步骤一:MinGW安装MinGW(MinimalistGNUforWindows)是一款在Windows平台使用的开发工具集,提供了C/C++编译工具。MinGW下载地址:WinLibs-适用于Windows的GCC+Mi......
  • C++创建与调用dll动态链接库
    C++创建与调用dll动态链接库(MinGW64Dev-C++)本文使用的是dev-c++,如果涉及到VC++中不一样的操作,也会适当进行区分。项目一:创建DLL1、创建一个DLL类型的项目,当前命名为dlltest,并选择合适的路径进行保存。 2、在生成的预设置代码中,加入如下代码//这是头文件dll.h#ifndef_D......
  • C/C++ 学生管理系统的文件读取与写入
    代码中文件读取函数read_file()存在一些问题,望指出.`#includeincludedefineSIZE100usingnamespacestd;staticintnums_stu=0;typedefstructStudent{char*name;char*ID; //占10个字符doublescore_one;doublescore_two;doublescore_three;doubletota......