文章目录

  • 概念
  • 用法
    • 特殊情况
  • 我的奇怪方法

概念

什么是高斯消元?让我们看一看 OI-Wiki 的解释:

高斯消元法(Gauss–Jordan elimination)是求解线性方程组的经典算法,它在当代数学中有着重要的地位和价值,是线性代数课程教学的重要组成部分。

高斯消元法除了用于线性方程组求解外,还可以用于行列式计算、求矩阵的逆,以及其他计算机和工程方面。

通俗来讲,就是解多元一次方程。

用法

高斯消元法的核心思想和它的名字一样:消元。为了方便讲解,现在让我们写出一个三元一次方程组:

{ x + y + z = 6 1 ◯ 5 x + 3 y + 2 z = 17 2 ◯ 3 x + 2 y + z = 10 3 ◯ \begin{cases}x+y+z=6\ \textcircled{1}\\5x+3y+2z=17\ \textcircled{2}\\3x+2y+z=10\ \textcircled{3}\end{cases} x+y+z=6 15x+3y+2z=17 23x+2y+z=10 3

相信各位读者一定一眼就看得出答案,但计算机不是人,不像各位读者那么聪明(就我一个蒟蒻,呜呜呜),于是请各位读者跟随我穿越时光,回到初二的课堂。

初中老师讲过二元一次方程组的求解方法有两种:代入消元法和加减消元法。代入消元就是指用一个未知数表示出另一个未知数,然后再代入到另一个方程里,而加减消元法则是通过两个方程括倍再通过加减法消掉一个未知数。

相信各位读者已经想到高斯消元到底是什么了。好的,本期讲解完毕,我们下次再见!

开个玩笑,我们继续。

刚才我们说到二元一次方程组的求解方式有加减消元和代入消元,那我们现在把它们扩展到 n n n 元一次方程组,结果会怎么样呢?

答案:代入消元太复杂,加减消元得高消。

这里的高消就是指高斯消元。

很明显,代入消元对计算机和程序员来讲难度太大了,因此,一位伟大的数学家——高斯,便发明了高斯消元(不知他的初衷是啥)!

高斯消元的做法是这样的:首先把每一项的系数和右边的常数项提取出来构成矩阵,比如上面的那个方程就可以被转化成这样:

{ x + y + z = 6 5 x + 3 y + 2 z = 17 3 x + 2 y + z = 10 → [ 1 1 1 6 5 3 2 17 3 2 1 10 ] \begin{cases}x+y+z=6\\5x+3y+2z=17\\3x+2y+z=10\end{cases}\to\begin{bmatrix}1&1&1&6\\5&3&2&17\\3&2&1&10\end{bmatrix} x+y+z=65x+3y+2z=173x+2y+z=10 15313212161710

接着让我们把第 i i i 行第 i i i 列的数变成 1 1 1,也就是给第 i i i 行的每个数除以 a i , i a_{i,i} ai,i,在上面的矩阵中我们先处理第一行:

[ 1 1 1 6 5 3 2 17 3 2 1 10 ] → [ 1 1 1 6 5 3 2 17 3 2 1 10 ] \begin{bmatrix}1&1&1&6\\5&3&2&17\\3&2&1&10\end{bmatrix}\to\begin{bmatrix}1&1&1&6\\5&3&2&17\\3&2&1&10\end{bmatrix} 15313212161710 15313212161710

然后我们以第 i i i 行第 i i i 列的数为基准,把第 i i i 列第 i i i 行下面的所有数变成 0 0 0,这一步解释起来有点复杂,大家自己看图:

[ 1 1 1 6 5 3 2 17 3 2 1 10 ] ⇒ [ 1 1 1 6 5 − 5 × 1 3 − 5 × 1 2 − 5 × 1 17 − 5 × 6 3 − 3 × 1 2 − 3 × 1 1 − 3 × 1 10 − 3 × 6 ] ⇒ [ 1 1 1 6 0 − 2 − 3 − 13 0 − 1 − 2 − 8 ] \begin{aligned}&\begin{bmatrix}1&1&1&6\\5&3&2&17\\3&2&1&10\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\5-5\times1&3-5\times1&2-5\times1&17-5\times6\\3-3\times1&2-3\times1&1-3\times1&10-3\times6\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&-2&-3&-13\\0&-1&-2&-8\end{bmatrix}\end{aligned} 15313212161710 155×133×1135×123×1125×113×16175×6103×6 1001211326138

最后重复上述操作,直到形成一个上三角结构,为了方便读者理解,这里把全过程展示了出来:

[ 1 1 1 6 0 − 2 − 3 − 13 0 − 1 − 2 − 8 ] ⇒ [ 1 1 1 6 0 − 2 ÷ ( − 2 ) − 3 ÷ ( − 2 ) − 13 ÷ ( − 2 ) 0 − 1 − 2 − 8 ] ⇒ [ 1 1 1 6 0 1 3 2 13 2 0 − 1 − 2 − 8 ] ⇒ [ 1 1 1 6 0 1 3 2 13 2 0 − 1 − 1 × ( − 1 ) − 2 − 3 2 × ( − 1 ) − 8 − 13 2 × ( − 1 ) ] ⇒ [ 1 1 1 6 0 1 3 2 13 2 0 0 − 1 2 − 3 2 ] ⇒ [ 1 1 1 6 0 1 3 2 13 2 0 0 − 1 2 ÷ ( − 1 2 ) − 3 2 ÷ ( − 1 2 ) ] ⇒ [ 1 1 1 6 0 1 3 2 13 2 0 0 1 3 ] \begin{aligned}&\begin{bmatrix}1&1&1&6\\0&-2&-3&-13\\0&-1&-2&-8\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&-2\div(-2)&-3\div(-2)&-13\div(-2)\\0&-1&-2&-8\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&1&\frac{3}{2}&\frac{13}{2}\\0&-1&-2&-8\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&1&\frac{3}{2}&\frac{13}{2}\\0&-1-1\times(-1)&-2-\frac{3}{2}\times(-1)&-8-\frac{13}{2}\times(-1)\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&1&\frac{3}{2}&\frac{13}{2}\\0&0&-\frac{1}{2}&-\frac{3}{2}\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&1&\frac{3}{2}&\frac{13}{2}\\0&0&-\frac{1}{2}\div(-\frac{1}{2})&-\frac{3}{2}\div(-\frac{1}{2})\end{bmatrix}\\&\Rightarrow\begin{bmatrix}1&1&1&6\\0&1&\frac{3}{2}&\frac{13}{2}\\0&0&1&3\end{bmatrix}\end{aligned} 1001211326138 10012÷(2)113÷(2)2613÷(2)8 100111123262138 1001111×(1)123223×(1)62138213×(1) 10011012321621323 10011012321÷(21)621323÷(21) 100110123162133

于是我们就得到了一个上三角结构的矩阵(即下半部分的三角形全是 0 0 0),而它的等效方程就是这个:

[ 1 1 1 6 0 1 3 2 13 2 0 0 1 3 ] ⇔ { x + y + z = 6 y + 3 2 z = 13 2 z = 3 \begin{bmatrix}1&1&1&6\\0&1&\frac{3}{2}&\frac{13}{2}\\0&0&1&3\end{bmatrix}\Leftrightarrow\begin{cases}x+y+z=6\\y+\frac{3}{2}z=\frac{13}{2}\\z=3\end{cases} 100110123162133 x+y+z=6y+23z=213z=3

接下来就是最重要的一步了:代入消元。有人会问:坐着你前面不是说代入消元很麻烦吗,怎么现在又要代入消元了?是不是玩不起啊?

其实不是的,因为通过观察左边的那个方程,我们会发现 z z z 的值实际上已经解开了,对应到矩阵上就是最后一行的倒数第二个是一个 1 1 1,而前面的数全是 0 0 0,这时最后一行的最后一个数就是最后的那个未知数的解,记录下来。

然后回到倒数第二行,我们不难发现:除了倒数第二个数(注意:我这里没写第二个,而写的是倒数第二个)是 1 1 1 之外,其他的不是 0 0 0 就是其他乱七八糟的数,在右边的方程中,我们在把 z z z 解开后肯定是带入到倒数第二个方程中,解开 y y y,而对应在左边的矩阵里就是用最后一个数减去最后那个数乘以下面那个未知数的值,于是得到了 y = 2 y=2 y=2 这个解,记录下来。

然后就不需要我讲了吧。(不会有人不会举一反三吧。)

特殊情况

上面的操作中,由于我们过分理想化的假设,导致我们没遇到一种特殊情况:系数为 0 0 0!我们举个例子看看会发生什么:

{ y + z = 3 x + z = 4 x + y = 5 \begin{cases}y+z=3\\x+z=4\\x+y=5\end{cases} y+z=3x+z=4x+y=5

画成矩阵:

[ 0 1 1 3 1 0 1 4 1 1 0 5 ] \begin{bmatrix}0&1&1&3\\1&0&1&4\\1&1&0&5\end{bmatrix} 011101110345

然后按照上面的步骤:首先我们需要将 a 1 , 1 a_{1,1} a1,1 变成 1 1 1。但我们发现个事: a 1 , 1 = 0 a_{1,1}=0 a1,1=0!按照正常的做法只需要除以一个 a 1 , 1 a_{1,1} a1,1 就行了,但是没有除以 0 0 0 这个东西啊喂!于是你的程序会直接 R E \color{purple}{RE} RE 掉。

但是这个方程没有解吗?并不是。上过小学奥数或者初中的人都知道这个方程有解 { x = 3 y = 2 z = 1 \begin{cases}x=3\\y=2\\z=1\end{cases} x=3y=2z=1(呀,一不小心说出答案了),那这是怎么一回事呢?

原因很简单:只是因为这个方程刚好系数为 0 0 0。你看下一个方程系数不就又是 1 1 1 了吗?因此我们可以适当把第二行和第一行的数换个位置,于是这个矩阵变成了这样:

[ 1 0 1 4 0 1 1 3 1 1 0 5 ] \begin{bmatrix}1&0&1&4\\0&1&1&3\\1&1&0&5\end{bmatrix} 101011110435

然后就可以快乐的解方程了。

总结一下: 规则就两条:

  1. 能直接解的直接解。
  2. 不能直接解的换两行再解。

最后说明一下判无解和无数解的办法:无解就是存在某一行除了最后一列其他全是 0 0 0,无数解就是存在一行全是 0 0 0

浅浅算一下时间复杂度: O ( n 3 ) O(n^3) O(n3)

代码太简单,就不展示了。(我绝对不会告诉你是因为我不会写。)

但是!


我的奇怪方法

由于本蒟蒻太菜,实在不会写高消,于是我自己再高消的基础上改了一下。

首先,我不需要换行,对于每一行我都遍历一遍找一个主元,而不是一定以第 i i i 行的第 i i i 个为主元。

其次,我每次消是把这一列全消成 0 0 0(除这个主元之外),这样最后就是一个 01 01 01 矩阵。

最后,我不需要还原,因为左边是个 01 01 01 矩阵,所以系数只有可能是 0 0 0 1 1 1,所以直接输出最后一列就行。

当然,我的解是随机分布的,因此需要拿个标记数组标记每个解再第几行再输出。

时间复杂度: O ( n 3 ) O(n^3) O(n3)

代码:

//洛谷P3389
#include<bits/stdc++.h>
#define int long long
#define code using
#define by namespace
#define plh std
code by plh;
int n,vis[106],h[106];
const double eps=1e-7;
double a[106][106],f[106];
void Gauss()
{for(int i=1;i<=n;i++){int id=0;for(int j=1;j<=n;j++){if(fabs(a[i][j])>eps&&!vis[j]){id=j;break;}}if(id){vis[id]=1;h[id]=i;for(int j=1;j<=n;j++){if(j!=id){a[i][j]/=a[i][id];}}f[i]/=a[i][id];a[i][id]=1;for(int j=1;j<=n;j++){if(j!=i){for(int k=1;k<=n;k++){if(k!=id){a[j][k]-=a[i][k]*a[j][id];}}f[j]-=f[i]*a[j][id];a[j][id]=0;}}}else{if(fabs(f[i])>eps){cout<<"No Solution";n=0;return;}}}
}
signed main()
{cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];}cin>>f[i];}Gauss();if(!n){return 0;}for(int i=1;i<=n;i++){if(!vis[i]){cout<<"No Solution";return 0;}}for(int i=1;i<=n;i++){printf("%0.2lf\n",f[h[i]]);}return 0;
}

说句实话,这篇文章制作非常不易(特别是 LateX 那一部分,真的是一个字一个字打出来的),希望读者能点个赞,非常感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87483.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87483.shtml
英文地址,请注明出处:http://en.pswp.cn/web/87483.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目

近日&#xff0c;武汉暴雨信息发展有限公司在激烈的竞争中脱颖而出&#xff0c;成功中标华中科技大学集成电路学院的服务器采购项目。此次中标产品为暴雨旗下的塔式重装AM400服务器&#xff0c;这一成果标志着暴雨信息在高性能计算领域的卓越实力得到了高校科研机构的高度认可。…

集群聊天服务器---MySQL数据库的建立

数据库的建立表格 user表 字段名称字段类型字段说明约束idINT用户idPRIMARY KEY, AUTO_INCREMENTnameVARCHAR(50)用户名NOT NULL, UNIQUEpasswordVARCHAR(50)用户密码NOT NULLstateENUM(online, offline)当前登录状态DEFAULT offline friend表 字段名称字段类型字段说明约束…

MongoDB 安装使用教程

一、MongoDB 简介 MongoDB 是一个高性能、开源的 NoSQL 文档型数据库&#xff0c;使用 BSON&#xff08;二进制 JSON&#xff09;格式存储数据。适合存储大规模、高并发的非结构化数据&#xff0c;常用于大数据、日志存储、微服务架构中。 二、下载安装 2.1 官网下载 访问 …

FastAPI 小白教程:从入门级到实战(源码教程)

目录 1. FastAPI 基本介绍 安装 FastAPI 2. 简单的 CRUD 示例 2.1 创建基本应用 2.2 添加 CRUD 操作​​​​​​​ 3. 处理跨域请求 (CORS) 4. 普通案例&#xff1a;待办事项 API​​​​​​​ 5. 企业案例&#xff1a;认证和数据库集成 5.1 使用 SQLAlchemy 和 JWT…

java中jasypt是用来做什么的?

思路&#xff1a; 简要介绍Jasypt&#xff1a;一句话说明它的作用。配置解析&#xff1a;分别解释password和algorithm的作用。工作流程&#xff1a;说明如何加密敏感数据并在配置文件中使用。安全提醒&#xff1a;强调密钥管理的重要性。 最终回答&#xff1a; Jasypt&…

牛客周赛 Round 98

1.小红与奇数 解题思路&#xff1a;如果给定的数是偶数, 由于1是任意正数的因子, 偶数1奇数 若给定的数是奇数, 1/自身, 都变成了偶数 #include <bits/stdc.h> using namespace std; void solve() {int x;cin >> x;if (x & 1)cout << "No" <…

(2)手摸手-学习 Vue3 之 变量声明【ref 和 reactive】

手摸手-学习 Vue3 之 变量声明【ref 和 reactive】 前言refreactive 前言 vue3 前端代码开发过程中&#xff0c;必然会涉及变量声明&#xff0c;会用到&#xff1a;ref、reactive 。本章节 进行讲解说明。 演示的项目&#xff0c;经处理后的结构如下&#xff1a; ref 用途…

[Terence Tao访谈] 无限 | 关注模型 | 矢量场 | 策略性“作弊” | Lean

关注模型 改变视角真的很重要 无限&#xff1a;假设是球形的奶牛 陶哲轩&#xff1a;一个很好的例子是数学中的塞迈雷迪定理&#xff0c;于1970年代得以证明&#xff0c;它涉及在一组数字集合中寻找某种类型的模式&#xff0c;即等差数列&#xff0c;例如3、5、7或10、15、20。…

汽车v型推力杆总成三维5自由度性能及疲劳测试系统

V型推力杆总成装置&#xff0c;通常设置在载重汽车中、后桥上&#xff0c;成对使用。其一端通过球面销与车架铰接&#xff0c;另一端则安装在车桥上&#xff0c;通过关节轴承与车桥铰接&#xff0c;其主要作用是稳定车桥&#xff0c;保持车桥的稳定位置&#xff0c;同时克服弹簧…

制动系统故障定义与诊断标准

核心定义&#xff1a; 制动不足 (Brake Insufficiency) 定义&#xff1a;制动系统产生的实际制动力低于预期制动力&#xff0c;但未完全丧失制动能力 关键特征&#xff1a; 制动距离增加20%以上 减速度低于预期值30%-50% 制动踏板行程异常增长 等效物理描述&#xff1a;&a…

server-rs

今天早上 看到有人 用cursor写rust东西了 效果不错遂尝试写一下web serverserver本身这个词就不确指单单这一个东西在与cursor交流中,还是越来越明白了之前 没有管过的一些"常识"一个业务服务之所以能“一直处理请求”&#xff0c;是因为有一个“东西”在背后做着持续…

python打卡day59@浙大疏锦行

知识点回顾&#xff1a; SARIMA模型的参数和用法&#xff1a;SARIMA(p, d, q)(P, D, Q)m模型结果的检验可视化&#xff08;昨天说的是摘要表怎么看&#xff0c;今天是对这个内容可视化&#xff09;多变量数据的理解&#xff1a;内生变量和外部变量多变量模型 统计模型&#xff…

Redisson的分布式锁源码分析2

文章目录Redisson的读写锁使用加锁源码分析释放锁源码分析&#xff1a;Redisson一次加多个锁RedissonMultiLock加锁源码分析&#xff1a;RedissonMultiLock释放锁源码分析&#xff1a;RCountDownLatch介绍&#xff1a;RCountDownLatch源码分析&#xff1a;RSemaphore分布式信号…

系统架构设计师论文分享-论软件过程模型及应用

我的软考历程 摘要 2023年2月&#xff0c;我所在的公司通过了研发纱线MES系统的立项&#xff0c;该系统为国内纱线工厂提供SAAS服务&#xff0c;旨在提升纱线工厂的数字化和智能化水平。我在该项目中担任架构设计师&#xff0c;负责该项目的架构设计工作。本文结合我在该项目…

云原生Kubernetes系列 | etcd3.5集群部署和使用

云原生Kubernetes系列 | etcd3.5集群部署和使用 1. etcd集群部署2. etcd集群操作3. 新增etcd集群节点1. etcd集群部署 etcd3.5官网站点:    https://etcd.io/docs/v3.5/op-guide/clustering/    https://etcd.io/docs/v3.5/tutorials/how-to-setup-cluster/ [root@localh…

helm安装配置jenkins

1、k8s1.28.2、helm3.12.0&#xff0c;集群搭建 查看节点运行情况 kubectl get node -o wide openebs部署情况 kubectl get sc -n openebs 2、添加Jenkins Helm仓库 helm repo add jenkins https://charts.jenkins.iohelm repo update# 查看版本 helm search repo -l jen…

Wagtail - Django 内容管理系统

文章目录 一、关于 Wagtail1、项目概览2、相关链接资源3、功能特性 二、安装配置三、使用入门1、快速开始2、兼容性 四、其它社区与支持1、社区资源2、商业支持 开发贡献参考项目参考文献 一、关于 Wagtail 1、项目概览 Wagtail 是一个基于 Django 构建的开源内容管理系统&am…

Spring AI Alibaba 来啦!!!

博客标题&#xff1a;Spring AI Alibaba&#xff1a;深度解析其优势与阿里云生态的无缝集成 引言 随着人工智能技术的快速发展&#xff0c;越来越多的企业和开发者开始关注如何将 AI 技术融入到现有的应用开发框架中。Spring AI 作为 Spring 框架在 AI 领域的扩展&#xff0c;…

【论文阅读39】PINN求边坡内时空变化的地震动响应(位移、速度、加速度)场分布

论文提出了一种基于物理信息神经网络&#xff08;PINN&#xff09;和极限分析上界定理相结合的岩体边坡地震稳定性分析框架&#xff0c;重点考虑了边坡中的预存裂缝对稳定性的影响。 PINN用来求解岩质边坡内随时间和空间变化的地震动响应&#xff08;位移、速度、加速度&#…

驱动开发系列59- 再述如何处理硬件中断

在本文中,我们将重点讨论编写设备驱动程序时一个非常关键的方面:什么是硬件中断,更重要的是,作为驱动开发者,你该如何准确地处理它们。事实上,大量的外设(也就是你可能会为其编写驱动的设备)在需要操作系统或驱动程序立即响应时,通常会通过触发硬件中断的方式发出请求…