矩阵、高斯消元、行列式及相关结论学习笔记(没写完)

矩阵、高斯消元、行列式及相关结论学习笔记

矩阵的概念

矩阵可以简单理解为二维数组。在 OI 中,矩阵的元素一般为整数或实数。

矩阵 A 的第 i 行、第 j 列元素记作 aij

仅有一行的矩阵称为行向量,只有一列的矩阵称为列向量。

矩阵左上到右下的对角线称为主对角线,右上到左下的对角线称为副对角线。

矩阵的运算

矩阵加法

矩阵加法就是对应位置相加。只有同型矩阵才能进行加法运算。

例如:

[121032]+[301110]=[1+32+01+10+13+12+0]=[422142]

矩阵加法满足:

  • 结合律:(A+B)+C=A+(B+C)
  • 交换律:A+B=B+A

矩阵减法

矩阵减法就是对应位置相减。只有同型矩阵才能进行减法运算。

矩阵数乘

矩阵数乘就是每个位置相乘。

例如:

2[203121]=[222023212221]=[406242]

矩阵数乘满足:

  • λ(μA)=μ(λA)=(λμ)A
  • (λ+μ)A=λA+μA
  • λ(A+B)=λA+λB

矩阵乘法

矩阵乘法有意义当且仅当第一个矩阵 A 的列数与第二个矩阵 B 的行数相等。设 A,B 的大小分别为 n×m,m×k,则 C=AB 的大小为 n×k。其中:

cij=r=1mairbrj

例如:

[102131]×[312110]=[13+02+2111+01+2013+32+1111+31+10]=[5142]

矩阵乘法满足:

  • 结合律:(AB)C=A(BC)
  • 对加法的左分配律:(A+B)C=AC+BC
  • 对加法的右分配律:C(A+B)=CA+CB

矩阵乘法不满足交换律。

行数、列数相同的矩阵有单位矩阵,其中 eij=[i=j]。例如,大小为 3×3 的单位矩阵如下:

[100010001]

单位矩阵 E 满足:

  • EA=AE=A

矩阵的幂

矩阵的幂有意义当且仅当行数、列数相同。

矩阵 Ak 次幂 Ak 等于 A 自乘 k 次的结果。

显然,矩阵的幂可以使用快速幂加速。

矩阵转置

将矩阵 A 的行和列交换得到转置矩阵 AT

例如:

[203121]T=[210231]

矩阵转置满足:

  • (AT)T=A
  • (λA)T=λAT
  • (AB)T=BTAT

高斯-约当消元法(Gauss-Jordan Elimination)

简介

高斯消元法是用于求解线性方程组的经典算法。

初等行变换

矩阵的初等行变换包括:

  • 交换矩阵的两行。
  • 以一个非零数 k 乘矩阵的某一行。
  • 将矩阵的某一行的 k 倍加到另一行。

同理可以定义初等列变换。

增广矩阵

对于线性方程组:

{a11x1+a12x2+a13x3++a1nxn=b1a21x1+a22x2+a23x3++a2nxn=b2a31x1+a32x2+a33x3++a3nxn=b3an1x1+an2x2+an3x3++annxn=bn

定义它的增广矩阵为:

[a11a12a13a1nb1a21a22a23a2nb2a31a32a33a3nb3an1an2an3annbn]

高斯消元

容易发现,对增广矩阵进行初等行变换不会改变方程组的解。

我们的目标就是利用初等行变换将增广矩阵变为如下形式:

[1000x10100x20010x30001xn]

则最右侧的一列就是方程组的解。如果无法变为该形式,则方程无解或无唯一解,可以进一步进行判定。

高斯消元的流程是:

  • 初始时令 i=1
  • 在第 in 行找出一行,使得第 i 列不为 0,并将该行与第 i 行交换(为减小浮点数运算导致的精度误差,通常选取绝对值最大的数那一行)。
  • 将该行的若干倍加到每一行,使得其余行的第 i 列均为 0
  • i<n,令 i 自增一,回到第二步;否则,进行下一步。
  • 对于每一行 i 计算得 xi=biaii

时间复杂度为 O(n3)

代码
const double eps = 1e-6;
bool gauss() {
	for(int i = 1; i <= n; i++) {
		int u = i;
		for(int j = i + 1; j <= n; j++) if(fabs(a[j][i]) > fabs(a[u][i])) u = j;
		swap(a[i], a[u]);
		if(fabs(a[i][i]) < eps) return 0; // 无解或无唯一解
		for(int j = 1; j <= n; j++) {
			if(i != j) {
				double mt = a[j][i] / a[i][i];
				for(int k = 1; k <= n + 1; k++) a[j][k] -= mt * a[i][k];
			}
		}
	}
	for(int i = 1; i <= n; i++) a[i][n+1] /= a[i][i];
	return 1; 
}

矩阵求逆

n×n 的矩阵 A 的乘法逆元存在,当且仅当该矩阵的秩为 n

矩阵 A 的秩 rkA 是它的线性无关的行数。

类似于高斯消元的增广矩阵,矩阵求逆只需要在原矩阵 A 右侧加上一个 n×n 的单位阵 I,然后进行初等行变换将左侧消成单位阵 I,此时右侧的矩阵即为 A1

代码
//By: Luogu@rui_er(122461)
#include <bits/stdc++.h>
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;
const int N = 805, mod = 1e9+7;

int n, a[N][N];
template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}
int qpow(int x, int y) {
	int ans = 1;
	for(;y;y>>=1,x=1LL*x*x%mod) if(y & 1) ans = 1LL * ans * x % mod;
	return ans;
}
int inv(int x) {return qpow(x, mod-2);}
bool gauss() {
	rep(i, 1, n) {
		int u = i;
		rep(j, i+1, n) if(a[j][i]) u = j;
		swap(a[i], a[u]);
		if(!a[i][i]) return 0;
		rep(j, 1, n) {
			if(i == j) continue;
			int mt = (-1LL * a[j][i] * inv(a[i][i]) % mod + mod) % mod;
			rep(k, i, 2*n) a[j][k] = (a[j][k] + 1LL * mt * a[i][k] % mod) % mod;
		}
	}
	rep(i, 1, n) {
		rep(j, n+1, 2*n) {
			a[i][j] = 1LL * a[i][j] * inv(a[i][i]) % mod;
		}
	}
	return 1;
}

int main() {
	scanf("%d", &n);
	rep(i, 1, n) rep(j, 1, n) scanf("%d", &a[i][j]);
	rep(i, 1, n) rep(j, n+1, 2*n) a[i][j] = (i + n == j);
	if(gauss()) {
		rep(i, 1, n) {
			rep(j, n+1, 2*n) {
				printf("%d%c", a[i][j], " \n"[j==2*n]);
			}
		}
	}
	else puts("No Solution");
    return 0;
}

咕咕咕

posted @   rui_er  阅读(160)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示