前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >高斯约旦消元法求逆矩阵的思想(分块矩阵的逆矩阵)

高斯约旦消元法求逆矩阵的思想(分块矩阵的逆矩阵)

作者头像
全栈程序员站长
发布于 2022-07-29 05:20:56
发布于 2022-07-29 05:20:56
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

luogu P4783 【模板】矩阵求逆

题目描述

求一个 N × N N×N N×N的矩阵的逆矩阵。答案对 1 0 9 + 7 10^9+7 109+7取模。

1.逆矩阵的定义

假设 A A A 是一个方阵,如果存在一个矩阵 A − 1 A^{-1} A−1,使得 A − 1 A = I A^{-1}A=I A−1A=I 并且 A A − 1 = I AA^{-1}=I AA−1=I

那么,矩阵 A 就是可逆的, A − 1 A^{-1} A−1 称为 A 的逆矩阵

2.逆矩阵求法 —— 初等变换法(高斯-约旦消元)

0.高斯-约旦消元

详见P3389 【模板】高斯消元法题解部分

高斯约旦消元与高斯消元区别:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
高斯消元 -> 消成上三角矩阵 

高斯-约旦消元 -> 消成对角矩阵 

约旦消元法的精度更好,代码更简单,没有回带的过程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void Gauss_jordan(){ 
   
	/***** 行的交换&加减消元 *****/ 
	for(re int i=1,r;i<=n;++i){ 
   	//正在处理第i行 
		r=i;
		for(re int j=i+1;j<=n;++j) 
			if(fabs(a[j][i])>fabs(a[r][i])) r=j;
		if(fabs(a[r][i])<eps){ 
   
			puts("No Solution");return;
		}
		if(i!=r) swap(a[i],a[r]);
		
		for(re int k=1;k<=n;++k){ 
   
		//每一行都处理 
			if(k==i) continue;
			double p=a[k][i]/a[i][i];
			for(re int j=i;j<=n+1;++j) a[k][j]-=p*a[i][j];
		} 
	}	
	
	//上述操作后会剩下对角矩阵,答案要除以系数 
	for(re int i=1;i<=n;++i) printf("%.2lf\n",a[i][n+1]/a[i][i]);
}

1.矩阵求逆

思路

  • 求 A A A的逆矩阵,把 A A A和单位矩阵 I I I放在一个矩阵里
  • 对 A A A进行加减消元使 A A A化成单位矩阵
  • 此时原来单位矩阵转化成逆矩阵

原理 A − 1 ∗ [ A I ] = [ I A − 1 ] A^{-1} * [AI] = [I A^{-1}] A−1∗[AI]=[IA−1]

举个栗子 求 [ 2 − 1 0 − 1 2 − 1 0 − 1 2 ] \left[ \begin{matrix} 2 &amp; -1 &amp; 0 \\ -1 &amp; 2 &amp; -1 \\ 0 &amp; -1 &amp; 2 \end{matrix} \right] ⎣⎡​2−10​−12−1​0−12​⎦⎤​

首先 [ 2 − 1 0 1 0 0 − 1 2 − 1 0 1 0 0 − 1 2 0 0 1 ] \begin{bmatrix} 2 &amp; -1 &amp; 0 &amp; 1 &amp; 0 &amp; 0 \\ -1 &amp; 2 &amp; -1 &amp; 0 &amp; 1 &amp; 0 \\ 0 &amp; -1 &amp; 2 &amp; 0 &amp; 0 &amp; 1 \end{bmatrix} ⎣⎡​2−10​−12−1​0−12​100​010​001​⎦⎤​ 对左边进行消元可得 [ 2 − 1 0 1 0 0 0 3 2 − 1 1 2 1 0 0 0 4 3 1 3 2 3 1 ] \left[ \begin{matrix} 2 &amp; -1 &amp; 0 &amp; 1 &amp; 0 &amp; 0 \\ 0 &amp; \frac{3}{2} &amp; -1 &amp; \frac{1}{2} &amp; 1 &amp; 0 \\ 0 &amp; 0 &amp; \frac{4}{3} &amp; \frac{1}{3} &amp; \frac{2}{3} &amp; 1 \end{matrix} \right] ⎣⎡​200​−123​0​0−134​​121​31​​0132​​001​⎦⎤​ 此时已消成上三角矩阵,高斯消元开始回代,但约旦会消成对角矩阵 [ 2 0 0 3 2 1 1 2 0 3 2 0 3 4 3 2 3 4 0 0 4 3 1 3 2 3 1 ] \left[ \begin{matrix} 2 &amp; 0 &amp; 0 &amp; \frac{3}{2} &amp; 1 &amp; \frac{1}{2} \\ 0 &amp; \frac{3}{2} &amp; 0 &amp; \frac{3}{4} &amp; \frac{3}{2} &amp; \frac{3}{4} \\ 0 &amp; 0 &amp; \frac{4}{3} &amp; \frac{1}{3} &amp; \frac{2}{3} &amp; 1 \end{matrix} \right] ⎣⎡​200​023​0​0034​​23​43​31​​123​32​​21​43​1​⎦⎤​ 最后每行除以系数 [ 1 0 0 3 4 1 2 1 4 0 1 0 1 2 1 1 2 0 0 1 1 4 1 2 3 4 ] \left[ \begin{matrix} 1 &amp; 0 &amp; 0 &amp; \frac{3}{4} &amp; \frac{1}{2} &amp; \frac{1}{4} \\ 0 &amp; 1 &amp; 0 &amp; \frac{1}{2} &amp; 1 &amp; \frac{1}{2} \\ 0 &amp; 0 &amp; 1 &amp; \frac{1}{4} &amp; \frac{1}{2} &amp; \frac{3}{4} \end{matrix} \right] ⎣⎡​100​010​001​43​21​41​​21​121​​41​21​43​​⎦⎤​ 此时右半边即为所求

2.细节

  1. 开long long(不要冒风险,乘法很容易溢出)
  2. 模意义下除以一个数等于乘上逆元,可用快速幂求逆元(费马小定理)

C o d e Code Code

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<cstdio>
#include<cmath>
#define re register
#define il inline
#define ll long long
using namespace std;

il ll read(){ 
   
    ll s=0,f=0;char c=getchar();
    while(c<'0'||c>'9') f=(c=='-'),c=getchar();
    while(c>='0'&&c<='9') s=(s<<3)+(s<<1)+(c^'0'),c=getchar();
    return f?-s:s;
}

const int N=405,mod=1e9+7;
int n;
ll a[N][N<<1];
il ll qpow(ll x,ll k){ 
   
	ll ans=1;
	while(k){ 
   
		if(k&1) ans=ans*x%mod;
		x=x*x%mod;
		k>>=1;
	}
	return ans%mod;
}

il void Gauss_j(){ 
   	
	for(re int i=1,r;i<=n;++i){ 
   
		r=i;
		for(re int j=i+1;j<=n;++j)
			if(a[j][i]>a[r][i]) r=j;
		if(r!=i) swap(a[i],a[r]);
		if(!a[i][i]){ 
   puts("No Solution");return;}
		
		int kk=qpow(a[i][i],mod-2);	//求逆元 
		for(re int k=1;k<=n;++k){ 
   
			if(k==i) continue;
			int p=a[k][i]*kk%mod;
			for(re int j=i;j<=(n<<1);++j) 
				a[k][j]=((a[k][j]-p*a[i][j])%mod+mod)%mod;
		} 
		
		for(re int j=1;j<=(n<<1);++j) a[i][j]=(a[i][j]*kk%mod);
		//更新当前行 如果放在最后要再求一次逆元,不如直接放在这里 
	}	
	
	for(re int i=1;i<=n;++i){ 
   
		for(re int j=n+1;j<(n<<1);++j) printf("%lld ",a[i][j]);
		printf("%lld\n",a[i][n<<1]);
	}
}
int main(){ 
   
	n=read();
	for(re int i=1;i<=n;++i)
		for(re int j=1;j<=n;++j)
			a[i][j]=read(),a[i][i+n]=1;
	
	Gauss_j();
    return 0;
}

网上浏览一圈头都要炸掉,线性代数太可怕了,定义好多 最后只看懂了这种方法

有什么问题欢迎评论区指出 :)

参考文章

线性代数之——矩阵乘法和逆矩阵

逆矩阵的几种求法与解析(很全很经典)

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129183.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[笔记]高斯消元法与矩阵求逆
(a_{i,1} - a_{i,1} \times 1)x_1 + (a_{i,2} - a_{i,1} \times \dfrac{a_{1,2}}{a_{1,1}})x_2 + \ldots = b_i - a_{i,1} \times \dfrac{b_1}{a_{1,1}}
Clouder0
2022/09/23
1.2K0
矩阵求逆c++实现[通俗易懂]
高斯消元法可以用来找出一个可逆矩阵的逆矩阵。设A 为一个N * N的矩阵,其逆矩阵可被两个分块矩阵表示出来。将一个N * N单位矩阵 放在A 的右手边,形成一个N * 2N的分块矩阵B = [A,I] 。经过高斯消元法的计算程序后,矩阵B 的左手边会变成一个单位矩阵I ,而逆矩阵A ^(-1) 会出现在B 的右手边。假如高斯消元法不能将A 化为三角形的格式,那就代表A 是一个不可逆的矩阵。应用上,高斯消元法极少被用来求出逆矩阵。高斯消元法通常只为线性方程组求解。
全栈程序员站长
2022/09/25
1.7K0
矩阵求逆c++实现[通俗易懂]
P3389 【模板】高斯消元法
题目背景 Gauss消元 题目描述 给定一个线性方程组,对其求解 输入输出格式 输入格式: 第一行,一个正整数 nn 第二至 n+1n+1行,每行 n+1n+1 个整数,为 ,代表一组方程。 输出格式: 共n行,每行一个数,第 ii行为 (保留2位小数) 如果不存在唯一解,在第一行输出"No Solution". 输入输出样例 输入样例#1: 3 1 3 4 5 1 4 7 3 9 3 2 2 输出样例#1: -0.97 5.18 -2.39 说明 本来想深入的研究一下矩阵来着,, 结
attack
2018/04/12
2K0
高斯消元法(Gauss Elimination)【超详解&模板】
高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵。 高斯消元法的原理是: 若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程
Angel_Kitty
2018/04/09
20.3K0
高斯消元法(Gauss Elimination)【超详解&模板】
挑战程序竞赛系列(43):4.1矩阵 高斯消元
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77747706
用户1147447
2019/05/26
5670
Luogu P3232 [HNOI2013]游走 题解
在一个无向图中,小Z以1为起点,每次以相等的概率选择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z走到N(即终点),结束了这次游走,总得分为游走时经过的每一条边的编号之和。现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。 输入保证: 1. 30%的数据满足N<=10100%的数据满足2<=N<=500
yzxoi
2022/09/19
5210
Luogu P3232 [HNOI2013]游走 题解
高斯消元
众所周知,高斯消元是线性代数中重要的一课。通过矩阵来解线性方程组。高斯消元最大的用途就是用来解多元一次方程组。
ACM算法日常
2019/11/25
6400
hihoCoder #1195 : 高斯消元·一
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:喂不得了啦,那边便利店的薯片半价了! 小Hi:啥?! 小Ho:那边的便利店在打折促销啊。 小Hi:走走走,赶紧去看
attack
2018/04/12
6100
矩阵树定理
矩阵树定理:对于一个无向图 ,它的生成树个数等于其基尔霍夫矩阵任何一个 阶主子式的行列式的绝对值。
hotarugali
2022/03/01
5050
4. 基础数学初识
输出格式 共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No。
浪漫主义狗
2022/09/14
9800
4. 基础数学初识
YbtOJ 891「高斯消元」生日礼物
给定一个 n\times m 的矩阵,矩阵的每个位置上有一个灯泡,每个灯泡上有一个开关,一旦按下了位于 (x_0,y_0) 的灯泡的开关, 以及满足 x-x_0=1,y-y_0=2 或 x-x_0=2,y-y_0=1 的位置上的灯泡的开关状态都会改变。
yzxoi
2022/09/19
2820
YbtOJ 891「高斯消元」生日礼物
洛谷P2455 [SDOI2006]线性方程组(高斯消元)
题目描述 已知n元线性一次方程组。 其中:n<=50, 系数是[b][color=red]整数<=100(有负数),bi的值都是整数且<300(有负数)(特别感谢U14968 mmqqdd提出题目描述
attack
2018/04/19
7290
洛谷P2455 [SDOI2006]线性方程组(高斯消元)
HDU4418 Time travel(期望dp 高斯消元)
\(f[x] = \sum_{i = 1}^n f[to(x + i)] * p[i] + ave\)
attack
2019/01/03
5230
C++实现矩阵类(附代码和功能)
阅读这篇文章需要掌握C++类的知识以及线性代数的知识,如果有疑问,可在文章下方评论,作者会尽快回复;本文是在作者阅读了平冈和幸的程序员的数学3:线性代数之后而写,在代码设计上借鉴了书中的方法。
全栈程序员站长
2022/09/13
2K0
C++实现矩阵类(附代码和功能)
BZOJ3288: Mato矩阵(欧拉函数 高斯消元)
Mato同学最近正在研究一种矩阵,这种矩阵有n行n列第i行第j列的数为gcd(i,j)。
attack
2018/07/27
2270
YbtOJ 894「高斯消元」高维寻点
小 A 有一个 m 维空间。在这个空间中有 n 个特殊点,其中第 i 个特殊点 p_i 的坐标为 (x_{i,1},x_{i,2},\cdots,x_{i,m})。
yzxoi
2022/09/19
2950
线性代数整理(三)行列式特征值和特征向量
比方说在二维平面中,这里有三组二维向量,每组都有两个向量,那么每组向量的面积就可以表示它们的不同。当然这里说面积是针对二维平面来说的,在三维空间中,就是体积;在更高维度中,可能就是一个体,但这个体比较抽象
算法之名
2021/03/04
2.7K0
矩阵求逆的几种方法总结(C++)
文内程序旨在实现求逆运算核心思想,某些异常检测的功能就未实现(如矩阵维数检测、矩阵奇异等)。
xiaoxi666
2018/10/29
10.8K0
matlab高斯消元法求逆
算法实现基本与高斯消元法求解线性方程组相同,同样还是三层循环进行消元和回代,只是增广矩阵的规模由n×n+1变成了n×2n,因此算法复杂度仍然为O(n3)。
叶茂林
2023/10/09
2640
matlab高斯消元法求逆
【HDU 5833】Zhu and 772002(异或方程组高斯消元)
比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3的个数是奇数为1),3的对应奇偶值为01,于是12*3是完全平方数。
饶文津
2020/06/02
6260
相关推荐
[笔记]高斯消元法与矩阵求逆
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验