【C++】高斯消元算法
矩阵初等行变换法则
- 任一行可以与另一行进行加减。
- 任一行可以乘或除以一个非零常数(除其实就是乘一个倒数)。
- 任两行可以交换位置。
线性方程组
形如
a1,1x1+a1,2x2+⋯+a1,nxn=b1a2,1x1+a2,2x2+⋯+a2,nxn=bn⋮an,1x1+an,2x2+⋯+an,nxn=bna_{1,1}x_1+a_{1,2}x_2+\dots+a_{1,n}x_n=b_1 \\ a_{2,1}x_1+a_{2,2}x_2+\dots+a_{2,n}x_n=b_n \\ \vdots \\ a_{n,1}x_1+a_{n,2}x_2+\dots+a_{n,n}x_n=b_n a1,1x1+a1,2x2+⋯+a1,nxn=b1a2,1x1+a2,2x2+⋯+a2,nxn=bn⋮an,1x1+an,2x2+⋯+an,nxn=bn
其中,系数矩阵为
A=(a1,1a1,2…a1,na2,1a2,2…a2,n⋮⋮⋮⋮an,1an,2…an,n)A=\left( \begin{matrix} &a_{1,1} &a_{1,2} &\dots &a_{1,n} \\ &a_{2,1} &a_{2,2} &\dots &a_{2,n} \\ &\vdots &\vdots &\vdots &\vdots \\ &a_{n,1} &a_{n,2} &\dots &a_{n,n} \\ \end{matrix} \right) A=⎝⎜⎜⎜⎛a1,1a2,1⋮an,1a1,2a2,2⋮an,2……⋮…a1,na2,n⋮an,n⎠⎟⎟⎟⎞
右值向量(矩阵)为
B=(b1b2⋮bn)B=\left ( \begin{matrix} b_1\\ b_2\\ \vdots\\ b_n \end{matrix} \right) B=⎝⎜⎜⎜⎛b1b2⋮bn⎠⎟⎟⎟⎞
解向量为
X=(x1x2⋮xn)X=\left ( \begin{matrix} x_1\\ x_2\\ \vdots\\ x_n \end{matrix} \right) X=⎝⎜⎜⎜⎛x1x2⋮xn⎠⎟⎟⎟⎞
因此,方程组可表示为
AX=BAX=B AX=B
矩阵的秩
- 矩阵可由初等行变换化为行最简形矩阵,所谓行最简型矩阵,即在阶梯形矩阵中,若非零行的第一个非零元素全是1,且非零行的第一个元素1所在列的其余元素全为零,就称该矩阵为行最简形矩阵。矩阵的秩就是行最简形矩阵非零行的个数,以r(M)r(M)r(M)来表示矩阵MMM的秩。如:
M=(100−1010−20012)M=\left (\begin{matrix} &1 &0 &0 &-1 \\ &0 &1 &0 &-2 \\ &0 &0 &1 &2 \end{matrix} \right) M=⎝⎛100010001−1−22⎠⎞
则r(M)=3r(M)=3r(M)=3
高斯消元法(列主元法)
- 其实就是线性代数中的矩阵行化简算法。
思路
要解上述方程组,需要引入增广矩阵
(A⋮b)=(a1,1a1,2…a1,nb1a2,1a2,2…a2,nb2⋮⋮⋮⋮⋮an,1an,2…an,nbn)(A\vdots b)= \left( \begin{matrix} &a_{1,1} &a_{1,2} &\dots &a_{1,n} &b_1 \\ &a_{2,1} &a_{2,2} &\dots &a_{2,n} &b_2 \\ &\vdots &\vdots &\vdots &\vdots &\vdots \\ &a_{n,1} &a_{n,2} &\dots &a_{n,n} &b_n \\ \end{matrix} \right) (A⋮b)=⎝⎜⎜⎜⎛a1,1a2,1⋮an,1a1,2a2,2⋮an,2……⋮…a1,na2,n⋮an,nb1b2⋮bn⎠⎟⎟⎟⎞
其实就是在系数矩阵AAA右侧添加右值向量bbb
- 若r(A)=r(A⋮b)r(A)=r(A\vdots b)r(A)=r(A⋮b)且r(A)=nr(A)=nr(A)=n,则方程组有唯一解
- 若r(A)=r(A⋮b)r(A)=r(A\vdots b)r(A)=r(A⋮b)且r(A)≠nr(A)\ne nr(A)=n,则方程组有无穷个解
- 若r(A)≠r(A⋮b)r(A)\ne r(A\vdots b)r(A)=r(A⋮b),则方程组无解
算法思想
- 假设行数为1∼n1 \sim n1∼n,列数为1∼n+11\sim n+11∼n+1
化简矩阵
- 初始化当前行为i=1i=1i=1
- 在i∼ni\sim ni∼n行中寻找绝对值最大的aiia_{ii}aii所在行jjj (最大系数可减小误差)
- 若ajj=0a_{jj}=0ajj=0则说明r(A)≠nr(A)\ne nr(A)=n,无唯一解,返回falsefalsefalse
- 交换第i,ji,ji,j两行,使得增广矩阵保持为上三角矩阵
- 第iii行所有元素除以系数aiia_{ii}aii
- 若i=ni=ni=n说明这是末尾行,结束矩阵化简,在求解向量后返回1
- 第i+1∼ni+1\sim ni+1∼n行,减去ai+1,ia_{i+1,i}ai+1,i倍第iii行,消除其余行的第iii列系数
- i=i+1i=i+1i=i+1,跳回到第222步,寻找下一行
求解向量
此时矩阵为
(A⋮b)=(1a1,2…a1,nb11…a2,nb2⋱⋮1bn)(A\vdots b)= \left( \begin{matrix} &1 &a_{1,2} &\dots &a_{1,n} &b_1 \\ & &1 &\dots &a_{2,n} &b_2 \\ & & &\ddots & &\vdots \\ & & & &1 &b_n \\ \end{matrix} \right) (A⋮b)=⎝⎜⎜⎜⎛1a1,21……⋱a1,na2,n1b1b2⋮bn⎠⎟⎟⎟⎞
即
x1+a1,2x2+⋯+a1,nxn=b1x2+a2,3x3+⋯+a2,nxn=b2xn=bnx_1+a_{1,2}x_2+\dots +a_{1,n}x_n=b_1 \\ x_2+a_{2,3}x_3+\dots +a_{2,n}x_n=b_2 \\ x_n=b_n x1+a1,2x2+⋯+a1,nxn=b1x2+a2,3x3+⋯+a2,nxn=b2xn=bn
此时有
xn=bnxn−1=bn−1−an−1,n∗bn⋮x1=b1−a1,n∗bn−a1,n−1∗bn−1−…a1,2a2x_n=b_n \\ x_{n-1}=b_{n-1}-a_{n-1,n}*b_n \\ \vdots \\ x_1=b_{1}-a_{1,n}*b_n-a_{1,n-1}*b_{n-1}-\dots a_{1,2}a_2 xn=bnxn−1=bn−1−an−1,n∗bn⋮x1=b1−a1,n∗bn−a1,n−1∗bn−1−…a1,2a2
解向量为
X=(x1x2⋮xn)X=\left( \begin{matrix} x_1\\ x_2\\ \vdots\\ x_n \end{matrix} \right) X=⎝⎜⎜⎜⎛x1x2⋮xn⎠⎟⎟⎟⎞
算法模板
int gauss(double num[100][101],int n,double x[]){for(int i=0;i<n;i++){//循环n次,第i轮循环行为i~n-1,列为i~nint maxRow=i;//maxRow记录系数最大的行,作为被减行减小误差for(int j=i+1;j<n;j++){if(abs(num[j][i])>abs(num[maxRow][i])) maxRow=j;}if(abs(num[maxRow][i])<zero) return 0;//x系数为0则增广矩阵无唯一解,返回0if(maxRow!=i){//交换最大行到i行,使之保持为上三角矩阵for(int j=i;j<n+1;j++){swap(num[maxRow][j],num[i][j]);}}for(int j=n;j>=i;j--){//化最大行第一个系数为1num[i][j]/=num[i][i];//从后向前除以系数,否则需要临时变量记录[i][i]的系数}for(int j=i+1;j<n;j++){//被系数行减去for(int k=n;k>=i;k--){num[j][k]-=num[j][i]*num[i][k];//减去了系数行乘以对应系数}}}for(int i=n-1;i>=0;i--){//逆向求解向量x[i]=num[i][n];//赋初值使得ax=bfor(int j=i+1;j<n;j++)x[i]-=num[i][j]*x[j];//减去其他解向量}return 1;
}
例题
题目链接
题目背景
Gauss消元
题目描述
给定一个线性方程组,对其求解
输入格式
第一行,一个正整数 nnn
第二至 n+1n+1n+1行,每行n+1n+1n+1个整数,为a1,a2⋯ana_1, a_2 \cdots a_na1,a2⋯an和bbb,代表一组方程。
输出格式
共nnn行,每行一个数,第iii行为xix_ixi(保留2位小数)
如果不存在唯一解,在第一行输出"No Solution".
输入输出样例
- 输入 #1
3
1 3 4 5
1 4 7 3
9 3 2 2
- 输出 #1
-0.97
5.18
-2.39
- 说明/提示
1≤n≤100,∣ai∣≤104,∣b∣≤1041 \leq n \leq 100, \left | a_i \right| \leq {10}^4 , \left |b \right| \leq {10}^41≤n≤100,∣ai∣≤104,∣b∣≤104
AC代码
#include <iostream>
#include <algorithm>
#define zero 1e-10
using namespace std;
int gauss(double num[100][101],int n,double x[]){for(int i=0;i<n;i++){//循环n次,第i轮循环行为i~n-1,列为i~nint maxRow=i;//maxRow记录系数最大的行,作为被减行减小误差for(int j=i+1;j<n;j++){if(abs(num[j][i])>abs(num[maxRow][i])) maxRow=j;}if(abs(num[maxRow][i])<zero) return 0;//x系数为0则增广矩阵无唯一解,返回0if(maxRow!=i){//交换最大行到i行,使之保持为上三角矩阵for(int j=i;j<n+1;j++){swap(num[maxRow][j],num[i][j]);}}for(int j=n;j>=i;j--){//化最大行第一个系数为1num[i][j]/=num[i][i];//从后向前除以系数,否则需要临时变量记录[i][i]的系数}for(int j=i+1;j<n;j++){//被系数行减去for(int k=n;k>=i;k--){num[j][k]-=num[j][i]*num[i][k];//减去了系数行乘以对应系数}}}for(int i=n-1;i>=0;i--){//逆向求解向量x[i]=num[i][n];//赋初值使得ax=bfor(int j=i+1;j<n;j++)x[i]-=num[i][j]*x[j];//减去其他解向量}return 1;
}
int main(){int n;double num[100][101];//矩阵大小是n*n+1double x[100];//存储解向量xscanf("%d",&n);for(int i=0;i<n;i++){for(int j=0;j<n+1;j++){scanf("%lf",&num[i][j]);}}if(gauss(num,n,x)){for(int i=0;i<n;i++){printf("%.2lf\n",x[i]);}}else{printf("No Solution");}return 0;
}
/*
3
1 3 4 5
1 4 7 3
9 3 2 2
*/
【C++】高斯消元算法相关推荐
- Rocksdb Ribbon Filter : 结合 XOR-filter 以及 高斯消元算法 实现的 高效filter
文章目录 前言 XOR-filter 实现原理 xor filter 的构造原理 xor filter 构造总结 XOR-filter 和 ADD-filter对比 XOR-filter 在计算上的优 ...
- 数论 - 高斯消元算法
1.高斯消元 (1)定义 高斯消元法是求解线性方阵组的一种算法,它也可用来求矩阵的秩,以及求可逆方阵的逆矩阵.它通过逐步消除未知数来将原始线性系统转化为另一个更简单的等价的系统.它的实质是通过初等行变 ...
- 英特尔oneAPI—高斯消元算法并行化
英特尔oneAPI简介 Intel oneAPI是一个跨行业.开放.基于标准的统一的编程模型,旨在提供一个适用于各类计算架构的统一编程模型和应用程序接口.也就是说,应用程序的开发者只需要开发一次代码, ...
- [算法] 高斯消元详解
原文链接(强烈建议安利) 0.前置知识 知道如何解三元一次方程组 有手,有脑子 1.答案的表示与存储 先解一个方程组: 2x+3y+5z=31 x-4y -z=-6 4x+2y-5z=9 我们把这个方 ...
- 计算机编程 高斯消元,高斯-若尔当消元法
高斯-若尔当消元法(英语:Gauss-Jordan Elimination),或译为高斯-约旦消元法,简称G-J消元法,是数学中的一个算法,是高斯消元法的另一个版本.它在线性代数中用来找出线性方程组的 ...
- 第三十四章 数论——高斯消元解线性方程组
第三十四章 数论--高斯消元解线性方程组 一.高斯消元 1.线性方程组 2.高斯消元步骤 (1)数学知识铺垫 增广矩阵和阶梯矩阵 初等变换 (2)高斯消元步骤 二.代码模板 1.问题: 2.代码 一. ...
- 基于高斯消元的BATS码的改进译码算法
基于高斯消元的BATS码的改进译码算法 摘要 BATS 码的编译码原理: 改进的高斯消元的结论: 系数矩阵不满秩下可以解码部分包的情况: 摘要 BATS码:(Batched Sparse Codes, ...
- 【算法设计与分析基础】高斯消元
参考<算法导论>第七部分 算法问题选编中的第28章 矩阵运算. #include<iostream> using namespace std;/*** 一些矩阵例子*//* d ...
- {算法}高斯消元不高斯
高斯消元蛋白,由开挂数学家高斯命名.它可以在 O(n2) O(n^2)的时间内解出n元1次方程组. 功能这么强大,其实原理就是常用的"加减消元法". 首先,还是要将方程标准化,都( ...
最新文章
- MobileIMSDK连接后频繁掉线重连,提示会话超时失效,对方非正常退出或网络故障
- WindowsFormsHost使用问题
- java大组件_Java的三大组件
- 阿里巴巴对Java编程【应用结构】的规约
- storm的数据源编程单元Spout学习整理
- golang RWMutex读写互斥锁源码分析
- SAAS及PAAS的概念
- 数据结构算法题整理5
- webpower中小企业邮件营销指南
- Docker--一门值得你学习的手艺
- 大平原顾问快讯FRX移至新服务器
- Consumer is not subscribed to any topics or assigned any partitions
- goland切换换行/不换行快捷键
- 08年最感人的文章,不信你不哭
- 高维空间中椭圆的基本方程
- arcgis直方图工具在哪_这些分析工具都分不清?别说你懂数据分析!
- c语言用字符输出李字,二级C语言历年真题汇总__第10篇对文件的输入输出-李赛红.doc...
- 从零开始创建一个Android主屏幕Widget
- php 和 photoshop,pscc和ps有什么区别
- java学习书籍推荐