解线性方程组(一)——克拉默法则求解(C++)

克拉默法则

解线性方程组最基础的方法就是使用克拉默法则,需要注意的是,该方程组必须是线性方程组。
假设有方程组如下:
{ a 11 x 1 + a 12 x 2 + ⋯ + a 1 n x n = b 1 a 21 x 1 + a 22 x 2 + ⋯ + a 2 n x n = b 2 ⋯ ⋯ ⋯ a n 1 x 1 + a n 2 x 2 + ⋯ + a n n x n = b n \begin{cases} a_{11}x_1+a_{12}x_2+\cdots+a_{1n}x_n=b_1\\ a_{21}x_1+a_{22}x_2+\cdots+a_{2n}x_n=b_2\\ \cdots \qquad \qquad\cdots \qquad \qquad \cdots \\ a_{n1}x_1+a_{n2}x_2+\cdots+a_{nn}x_n=b_n\\ \end{cases} a11x1+a12x2++a1nxn=b1a21x1+a22x2++a2nxn=b2an1x1+an2x2++annxn=bn
将其转换为矩阵形式
A x ⃗ = b ⃗ A\vec{x}=\vec{b} Ax =b
[ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯ a m n ] [ x 1 x 2 ⋮ x n ] = [ b 1 b 2 ⋮ b n ] \begin{bmatrix} {a_{11}}&{a_{12}}&{\cdots}&{a_{1n}}\\ {a_{21}}&{a_{22}}&{\cdots}&{a_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{m1}}&{a_{m2}}&{\cdots}&{a_{mn}}\\ \end{bmatrix} \begin{bmatrix} {x_{1}}\\ {x_{2}}\\ {\vdots}\\ {x_{n}}\\ \end{bmatrix}= \begin{bmatrix} {b_{1}}\\ {b_{2}}\\ {\vdots}\\ {b_n} \end{bmatrix} a11a21am1a12a22am2a1na2namn x1x2xn = b1b2bn
根据克拉默法则有:
x i = ∣ A i ∣ ∣ A ∣ x_i=\frac{|A_i|}{|A|} xi=AAi
A i = [ a 11 ⋯ a 1 i − 1 b 1 a 1 i + 1 ⋯ a 1 n a 21 ⋯ a 2 i − 1 b 2 a 2 i + 1 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 ⋯ a n i − 1 b n a n i + 1 ⋯ a n n ] A_i= \begin{bmatrix} {a_{11}}&{\cdots}&{a_{1i-1}}&{b1}&{a_{1i+1}}&{\cdots}&{a_{1n}}\\ {a_{21}}&{\cdots}&{a_{2i-1}}&{b2}&{a_{2i+1}}&{\cdots}&{a_{2n}}\\ {\vdots}&{\vdots}&{\ddots}&{\vdots}\\ {a_{n1}}&{\cdots}&{a_{ni-1}}&{bn}&{a_{ni+1}}&{\cdots}&{a_{nn}}\\ \end{bmatrix} Ai= a11a21an1a1i1a2i1ani1b1b2bna1i+1a2i+1ani+1a1na2nann

代码

实现方法可以参考行列式求值(C++)、插值(一)——多项式插值(C++)

//克拉默法则求解线性方程组
/*
5x1+2x2-2x3=1
x1+4x2+x3=2
x1-2x2+4x3=-1
*/
#include<iostream>
#include<cmath>
//使用代数余子式进行求解
double determinant_value(double **D,int n)
{
    if(n==1)
    {
        return D[0][0];
    }
    else if(n==0){
        throw "error: determinant is empty";
    }
    char flag = 1;//符号位
    double D_value = 0.0;
    double **D_temp = new double*[n];
    for (int i = 0; i < n;i++)
    {
        D_temp [i]= new double[n];
        for(int j=0;j<n;j++)
        {
            D_temp[i][j]=D[i][j];
        }
    }
    // 转为上三角
    for (int i = 0; i < n; i++)
    {
        if (D_temp[i][i] == 0)
        {
            int j = i + 1;
            // 将主对角线上的值转为非0值
            for (; j < n; j++)
            {
                if (D_temp[j][i] != 0)
                {
                    double temp;
                    for (int k = 0; k < n; k++)
                    {
                        temp = D_temp[i][k];
                        D_temp[i][k] = D_temp[j][k];
                        D_temp[j][k] = temp; // 交换两行
                    }
                    flag = -flag;
                    break;
                }
            }
            if (j == n)
            {
                return D_value;
            }
        }
        // 将主对角线下面的值转为0
        for (int j = i + 1; j < n; j++)
        {
            double temp = D_temp[j][i] / D_temp[i][i];
            for (int k = i; k < n; k++)
            {
                D_temp[j][k] -= temp * D_temp[i][k];
            }
        }
    }
    // 计算行列式的值
    D_value = 1.0;
    for (int i = 0; i < n; i++)
    {
        D_value *= D_temp[i][i];
    }
    D_value*=flag;
    for (int i = 0; i < n;i++)
    {
        delete[] D_temp[i];
    }
    delete [] D_temp;
    return D_value;
}
//克拉默法则求解线性方程组
void Kramer(double **A,double *b,double *x,int n)
{
    double **A_i=new double*[n];
    double A_value=determinant_value(A,n);
    if(A_value==0)
    {
        std::cout<<"该方程组不是线性方程组"<<std::endl;
        exit(0);
    }
    for (int i = 0; i < n; i++)
    {
        A_i[i] = new double[n];
        for (int j = 1; j < n; j++)
        {
            A_i[i][j] = A[i][j];
        }
    }
    //下面是为了求D_i,每次只需要修改两列数据
    for (int i = 0; i < n;i++)
    {
        if(i==0)
        {
            for(int j = 0;j < n;j++)
            {
                A_i[j][0]=b[j];
            }
        }
        else{
            for(int i2 = 0;i2 < n;i2++)
            {
                A_i[i2][i-1]=A[i2][i-1];
                A_i[i2][i]=b[i2];
            }
        }
        // for(int i2 = 0;i2 < n;i2++)
        // {
        //     for (int j2 = 0;j2 < n;j2++)
        //     {
        //         std::cout<<A_i[i2][j2]<<" ";
        //     }
        //     std::cout<<std::endl;
        // }
        //求多项式系数
        x[i] = determinant_value(A_i, n) / A_value;
    }
    for (int i = 0; i < n; i++)
    {
        delete[] A_i[i];
    }
    delete[] A_i;
}
int main()
{
    int n;//矩阵维度
    std::cout<<"请输入矩阵维度:";
    std::cin>>n;
    double *x=new double[n];
    double **A = new double *[n];
    std::cout<<"请输入矩阵A的元素:"<<std::endl;
    for(int i = 0;i < n;i++)
    {
        A[i] = new double [n];
        for(int j = 0;j < n;j++)
        {
            std::cin>>A[i][j];
        }
    }
    double *b = new double [n];
    std::cout<<"请输入矩阵b的元素:"<<std::endl;
    for(int i = 0;i < n;i++)
    {
        std::cin>>b[i];
    }
    Kramer(A, b, x, n);
    for (int i = 0; i < n; i++)
    {
        std::cout<<"x"<<i+1<<"="<<x[i]<<" ";
    }
    for (int i = 0; i < n; i++)
    {
        delete[] A[i];
    }
    delete[] A;
    delete [] b;
    delete[] x;
    return 0;
}

结果分析

运行结果如下:
在这里插入图片描述

matlab结果如下:
在这里插入图片描述
此方法虽然可以求解,但是存在一个问题,就是当矩阵维度较大时,程序运行时间会很长,所以在一些精度要求不高的地方,不需要使用此方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/390566.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java集合 List接口

List接口操作 Java的List接口是Java集合框架中的一部分&#xff0c;它表示有序的集合。List接口提供了许多常用的方法&#xff0c;以下是其中的一些例子&#xff1a; 增加元素 add(E e)&#xff1a;将指定的元素插入此列表的末尾。 List<String> list new ArrayList…

【网工】华为设备命令学习(防火墙)

实验目的PC1连接到外网。 关于防火墙的其他知识后续补充。 ensp里的防火墙 用户名admin 密码Admin123 防火墙的接口类型 1.路由模式 物理口可以直接配. ​​​​​2.交换模式 物理口不能直接配IP&#xff0c;类似交换机&#xff0c;可以配vlan 首先我们先要对各个设备进…

unreal engine5.1中设置convex decomposition凸包分解

UE5系列文章目录 文章目录 UE5系列文章目录前言一、convex decomposition是什么&#xff1f;二、convex decomposition属性设置 前言 今天使用ue5根据网上教程制作可操控直升机&#xff0c;找属性convex decomposition凸包分解&#xff0c;默认的碰撞如下图 如果想使用精细化…

1、若依(前后端分离)框架的使用

若依&#xff08;前后端分离&#xff09;框架的使用 0、环境1、下载若依(1) 下载并解压(2) 导入SQL语句(3) 配置Redis、MySQL 2、运行若依3、登录(1) 前端(2) 后端 4、获取用户角色、权限和动态路由(1) 获取用户角色、权限(2) 根据用户信息获取动态路由【getRouters】 5、杂6、…

【C语言】指针练习篇(下),深入理解指针---指针练习题【图文讲解,详细解答】

欢迎来CILMY23的博客喔&#xff0c;本期系列为【C语言】指针练习篇&#xff08;下&#xff09;&#xff0c;深入理解指针---指针练习题【图文讲解,详细解答】&#xff0c;图文讲解指针练习题&#xff0c;带大家更深刻理解指针的应用&#xff0c;感谢观看&#xff0c;支持的可以…

人工智能专题:基础设施行业智能化的基础设施,自智网络双价值分析

今天分享的是人工智能系列深度研究报告&#xff1a;《人工智能专题&#xff1a;基础设施行业智能化的基础设施&#xff0c;自智网络双价值分析》。 &#xff08;报告出品方&#xff1a;埃森哲&#xff09; 报告共计&#xff1a;32页 自智网络驱动的电信产业变革 经过多年的…

飞天使-k8s知识点20-kubernetes实操5-pod更新与暂停-statefulset

文章目录 资源调度 Deployment&#xff1a;扩缩容资源调度 Deployment&#xff1a;更新的暂停与恢复资源调度 StatefulSet&#xff1a;定义一个有状态服务headless service 金丝雀发布 资源调度 Deployment&#xff1a;扩缩容 扩容和缩容&#xff0c;常用的功能 scale[rootkub…

Rust 学习笔记 - Hello world

前言 本文将讲解如何完成一个 Rust 项目的开发流程&#xff0c;从编写 “Hello, World!” 开始&#xff0c;到使用 Cargo 管理和运行项目。 编写 Hello world 开始一个新项目很简单&#xff0c;首先&#xff0c;创建一个包含 main.rs 文件的 hello_world 文件夹&#xff0c;…

持久化:Linux利用SUID、任务计划、vim进行权限维持

目录 利用Linux SUID进行权限维持 利用Linux计划任务进行权限维持 利用Vim创建后门 利用CVE-2019-12735进行权限维持 使用Vim运行Python后门程序 利用Linux SUID进行权限维持 在前面我们使用Linux的SUID权限进行了权限提升&#xff0c;然后SUID还可以用来进行持久化 利用…

什么是自编码器Auto-Encoder?

来源&#xff1a;https://www.bilibili.com/video/BV1Vx411j78H/?spm_id_from333.1007.0.0&vd_sourcef66cebc7ed6819c67fca9b4fa3785d39 为什么要压缩呢&#xff1f; 让神经网络直接从上千万个神经元中学习是一件很吃力的事情&#xff0c;因此通过压缩提取出原图片中最具代…

LabVIEW卫星电视接收仿真系统

LabVIEW卫星电视接收仿真系统 随着卫星电视数字化的加速&#xff0c;传统模拟信号接收系统已无法满足需求。设计一套船载数字卫星电视接收系统&#xff0c;通过LabVIEW环境进行仿真实验&#xff0c;验证系统设计的可行性与有效性&#xff0c;满足数字信号接收的高精度要求&…

mysql 2-15

书写规范 #单行注释 */多行注释 -- 单行注释 mysql导入数据 基本SELECT语句 列的别名 三种方式 查询去除重复行 空值参与运算 着重号&#xff0c;取消关键字 查询常数&#xff0c;向前面添加常数 显示表结构 过滤数据 不分大小写&#xff0c;SQL不严谨 数值运算符 号区别 …

7.JS里表达式,if条件判断,三元运算符,switch语句,断点调试

表达式和语句的区别 表达式就是可以被求值的代码比如什么a 1 语句就是一段可以执行的代码比如什么if else 直接给B站的黑马程序员的老师引流一波总结的真好 分支语句 就是基本上所有的语言都会有的if else 语句就是满足不同的条件执行不同的代码&#xff0c;让计算机有条件…

使用倒模耳机壳UV村脂胶液制作舞台监听耳返入耳式耳机壳有哪些优点?

使用倒模耳机壳UV树脂胶液制作舞台监听耳返入耳式耳机壳有很多优点&#xff0c;具体如下&#xff1a; 高音质表现&#xff1a;通过倒模工艺制作的耳机壳能够更好地贴合耳朵&#xff0c;减少声音散射和反射&#xff0c;提高声音的清晰度和质感。这对于舞台监听来说非常重要&…

智能传感器阅读笔记-物联网用智能传感器技术的发展重点

物联网用智能传感器技术的发展重点包含边缘计算算法优化、身份认证算法优化和能量采集技术。 图1 物联网用智能传感器技术的发展重点 边缘计算算法优化 边缘计算是指在靠近物或数据源头的一侧&#xff08;传感器侧&#xff09;&#xff0c;采用集检测、计算、存储、通信功能…

C语言从零实现贪吃蛇小游戏

制作不易&#xff0c;点赞关注一下呗&#xff01;&#xff01;&#xff01; 文章目录 前言一. 技术要点二、WIN32API介绍三、贪吃蛇游戏设计与分析 1.游戏开始前的初始化 2.游戏运行的逻辑 总结 前言 当我们掌握链表这样的数据结构之后&#xff0c;我们就可以用它来…

第12集《佛说四十二章经》

请大家打开讲议第十五面&#xff0c;第三十一章、心寂欲除。 这几章都是佛陀指导我们如何修出离心。前面的经文讲到修出离心&#xff0c;这有对外境与对内心的出离。对外境的出离是指一位初学者&#xff0c;选择一个如法清净的道场安住&#xff0c;这非常重要。唯识学对这个概…

紫微斗数双星组合:天机天梁在辰戌

文章目录 前言内容总结 前言 紫微斗数双星组合&#xff1a;天机天梁在辰戌 内容 紫微斗数双星组合&#xff1a;天机天梁在辰戌 性格分析 在紫微斗数命盘中&#xff0c;天梁星是一颗“荫星”&#xff0c;能够遇难呈祥&#xff0c;化解凶危&#xff0c;主寿&#xff0c;主贵。…

四、JMS规范

JMS规范 一、JMS是什么二、MQ中间件对比三、JMS组成1.JMS Provider2.JMS Producer3.JMS Consumer4.JSM Message4.1 消息头4.2 消息体4.2.1 生产者4.2.2 消费者 4.3 消息属性 四、JMS可靠性1.PERSISTENT - 持久化1.1 参数设置1.2 Queue持久化1.3 Topic持久化1.3.1 持久的发布主题…

开关式稳压电源的工作原理

随着全球对能源问题的重视&#xff0c;电子产品的耗能问题将愈来愈突出&#xff0c;如何降低其待机功耗&#xff0c;提高供电效率成为一个急待解决的问题。传统的线性稳压电源虽然电路结构简单、工作可靠&#xff0c;但它存在着效率低&#xff08;只有40% &#xff0d;50%&…