第一章、线性代数(2)高斯消元法

一、线性方程组

【线性方程组】

线性方程组是由n个m元一次方程共同构成。比如n = 3,m = 3时,有线性方程组:

如果把系数拿出来,就构成系数矩阵:

将系数和常数项拿出来,就构成增广矩阵:

二、高斯消元法

【高斯消元法】

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

高斯发现,在求解线性方程组时,当未知数排列整齐后,求解的过程只与系数和常数项有关。因此,只需要对增广矩阵执行相应操作即可。

其中,对增广矩阵执行下述三类操作,不会影响方程组的解:

1、交换两行;

2、某一行所有元素乘以一个数k,其中k不等于0;

3、将某一行所有元素的k倍加到另一行对应元素上。

这三种操作被称为矩阵的初等行变换。

【代码实现】

cpp 复制代码
const int N = 110;
const double eps = 1e-7;

int n;
double a[N][N];

inline bool zero(double x)
{
	return fabs(x) < eps;
}

int gauss()
{
	for(int i = 1; i <= n; i++)
	{
		int aim = i;
		// 找出第i列中,未确定主元的行中的最大行
		for(int j = 1; j <= n; j++)
		{
			// 判断是否确定主元
			if(j < i && !zero(a[j][j]))
				continue;
				
			if(fabs(a[j][i]) > fabs(a[aim][i]))
				aim = j;
		}
		
		if(zero(a[aim][i]))
			continue;
		
		// 交换aim行和i行	
		for(int j = 1; j <= n + 1; j++)
			swap(a[aim][j], a[i][j]);
		
		// a[i][i] 置为1	
		for(int j = n + 1; j >= i; j--)
			a[i][j] /= a[i][i];
		
		// 第i列除了第i行,全部消为0
		for(int j = 1; j <= n; j++)
		{
			if(j == i)
				continue;
				
			double t = a[j][i] / a[i][i];
			for(int k = i; k <= n + 1; k++)
			{
				a[j][k] -= a[i][k] * t;
			}
		}
	}
	
	// 判断解
	int ret = 1;  // 唯一解
	for(int i = 1; i <= n; i++)
	{
		if(zero(a[i][i]) && !zero(a[i][n + 1]))
		{
			ret = 0;  // 无解
			break;
		}
		if(zero(a[i][i]))
			ret = 2;  // 无数解
	}
	return ret;
}

三、矩阵求逆

cpp 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 410, mod = 1e9 + 7;
const double eps = 1e-7;
typedef long long LL;

int n;
LL a[N][N + N];

LL qpow(LL a, LL b, LL p)
{
	LL ret = 1;
	while (b)
	{
		if (b & 1)
			ret = ret * a % p;

		b >>= 1;
		a = a * a % p;
	}
	return ret;
}

int gauss()
{
	for (int i = 1;i <= n;i++)
	{
		int aim = i;
		for (int j = 1;j <= n;j++)
		{
			if (j < i && a[j][j] != 0)
				continue;

			if (a[j][i] > a[aim][i])
				aim = j;
		}

		if (a[aim][i] == 0)
			return 0;

		for (int j = 1;j <= n + n;j++)
			swap(a[aim][j], a[i][j]);

		LL t = qpow(a[i][i], mod - 2, mod);
		for (int j = n + n;j >= i;j--)
			a[i][j] = a[i][j] * t % mod;

		for (int j = 1;j <= n;j++)
		{
			if (i == j)
				continue;

			t = a[j][i];
			for (int k = i;k <= n + n;k++)
			{
				a[j][k] -= a[i][k] * t;
				a[j][k] = (a[j][k] % mod + mod) % mod;
			}
		}
	}

	return 1;
}

int main()
{
	cin >> n;
	for (int i = 1;i <= n;i++)
	{
		for (int j = 1;j <= n;j++)
		{
			cin >> a[i][j];
		}
	}

	for (int i = 1;i <= n;i++)
		a[i][i + n] = 1;

	int ret = gauss();
	if (ret == 0)
		cout << "No Solution" << endl;
	else
	{
		for (int i = 1;i <= n;i++)
		{
			for (int j = n + 1;j <= n + n;j++)
			{
				cout << a[i][j] << " ";
			}
			cout << endl;
		}
	}

	return 0;
}
相关推荐
zh_xuan4 小时前
LeeCode 496. 下一个更大元素I
数据结构·算法·栈·单调栈
机 _ 长4 小时前
05 智算运维|8 张卡怎么才算「捆成一张」:NCCL 实测与拓扑
运维·人工智能·算法·智算运维
早起CaiCai5 小时前
【2023-01 OM】利用深度学习算法融合异质观测实现海洋场降尺度
人工智能·深度学习·算法
梦里寻码6 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
猿人谷6 小时前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
青少儿编程课堂7 小时前
蓝桥杯青少组图形化 STEMA 省考(报名倒计时·11/22开考)+ 全国青少年信息素养大赛 2026—2027赛季 + 电子学会图形化考级:校园华容道大闯关
c++·python·算法·bfs·信息学竞赛
在猴站学算法8 小时前
(《统计学习方法》(第2版) 李航)第2章 感知机算法
学习·算法·机器学习·统计学习
Rainmicro8 小时前
【无标题】
java·数据库·算法
NEFU_Jyj18 小时前
牛客周赛R168
算法