首页 > 其他分享 >[学习笔记] 高斯消元 - 线性代数

[学习笔记] 高斯消元 - 线性代数

时间:2024-04-17 18:12:27浏览次数:15  
标签:int eps 笔记 主元 线性代数 消元 dt 高斯消

高斯-约旦消元

下面给两道板子

【模板】高斯消元法

最最基础的板子,没啥哆嗦的。下面给出高斯-约旦消元解法。

#include<bits/stdc++.h>
using namespace std;
int n, dt = 1;
double eps = 1e-9, m[102][102];
int main(){
	scanf("%d", &n);
	for(int i=1; i<=n; ++i)
	for(int j=1; j<=n+1; ++j)
		scanf("%lf", &m[i][j]);
	for(int i=1; i<=n; ++i){
		int mx = i;
		for(int j=i+1; j<=n; ++j)
			if(fabs(m[mx][i]) < fabs(m[j][i])) mx = j;
		if(fabs(m[mx][i]) < eps) dt = 0;
		swap(m[mx], m[i]);
		for(int j=n+1; j>=i; --j) m[i][j] /= m[i][i];
		for(int j=1; j<=n; ++j){
			if(j == i) continue;
			double t = m[j][i];
			for(int k=1; k<=n+1; ++k) m[j][k] -= t*m[i][k];
		}
	}
	if(!dt){
		printf("No Solution");
		return 0;
	}
	for(int i=1; i<=n; ++i) printf("%.2f\n", m[i][n+1]);
	return 0;
}

[SDOI2006] 线性方程组

这是一道很好的题(板子),跟上题唯一的区别就是判无解和无穷解。这题打通了说明你对高斯消元的理解也就差不多了。

搞了两天,终于把高斯-约旦消元的解调出来了。

高斯-约旦消元 和 高斯消元 的原理是一样的,只不过实现方式略有差别。高斯消元是先把主元以前的系数统统化为0,再回代求解;而高斯-约旦消元是把主元化为一,在把所有狮子的主元都化为0,让主元系数都为1并且在对角线上排列。

对于形如这样的狮子\([0\ 0\ 0\ …\ |\ k]\), 无解的判定方法是所有系数都为0但 \(k\) 不为0,无穷解的判定方式是所有系数都为0且 \(k\) 等于0 或存在某个主元都为0。易知:判定无解在先,其次为无穷解,最后输出答。

所以,在进行高-约消元的时候,如果出现个主元的最大值为0,那么会出现两种情况,要么无解,要么无穷解,所以要查一遍这个狮子的所有系数,看是否满足上述情况。如果判不出无解,这一列主元也就没用了,为了不影响后续的消元操作,那就把这一列全部移动到右边去。选出来的这一行也移动到下边去。所以最后消完元的子矩阵应该位于完整矩阵的左上角。最后再遍历一遍整个矩阵看是否无解即可。

注意细节。

#include<bits/stdc++.h>
using namespace std;
int n, dt = 1, a, b; // a b 分别代表当前的行和列 
double eps = 1e-9, m[52][52]; //eps为精度,因为涉及到小数运算,所以不太会出现完全等于0的数 
int main(){
	scanf("%d", &n);
	a = n, b = n+1;
	for(int i=1; i<=n; ++i)
	for(int j=1; j<=n+1; ++j)
		scanf("%lf", &m[i][j]);
	for(int i=1; i<=a; ++i){
		int mx = i;
		for(int j=i+1; j<=b; ++j)
			if(fabs(m[mx][i]) < fabs(m[j][i])) mx = j;
		if(fabs(m[mx][i]) < eps){ //如果主元都为0 
			bool cnt = 1;
			for(int j=i+1; j<=n; ++j) //查是否无解 
				if(fabs(m[mx][j]) >= eps) cnt = 0;
			if(cnt && fabs(m[mx][n+1]) >= eps){
				printf("-1");
				return 0;
			}
			dt = 0;
			swap(m[mx], m[a--]); //移动 
			--b;
			for(int j=1; j<=n; ++j) swap(m[j][i], m[j][b]); //移动 
			--i;
			continue; //一是防止报错 二是再消也没啥大用 毕竟主元都没了 
		}
		swap(m[mx], m[i]);
		for(int j=n+1; j>=i; --j){
			if(j >= b && j <= n) continue; //避免误判 
			m[i][j] /= m[i][i];
		}
		for(int j=1; j<=n; ++j){ //这里很重要,一定要把能消的都消干净 
			if(j == i) continue;
			double t = m[j][i];
			for(int k=1; k<=n+1; ++k) m[j][k] -= t*m[i][k];
		}
	}
//	for(int i=1; i<=n; ++i){
//		for(int j=1; j<=n+1; ++j){
//			printf("%.2f ", m[i][j]);
//		}printf("\n");
//	}
	for(int i=1; i<=n; ++i){ //再扫一遍 看是否无解 
		bool cnt = 1;
		for(int j=1; j<=n; ++j)
			if(fabs(m[i][j]) >= eps) cnt = 0;
		if(cnt && fabs(m[i][n+1]) >= eps){
			printf("-1");
			return 0;
		}
	}
	if(!dt){ //无穷解 
		printf("0");
		return 0;
	}
	for(int i=1; i<=n; ++i) printf("x%d=%.2f\n", i, m[i][n+1]);
	return 0;
}

标签:int,eps,笔记,主元,线性代数,消元,dt,高斯消
From: https://www.cnblogs.com/xiaolemc/p/18141424

相关文章

  • 后缀数组学习笔记
    定义后缀数组是什么?(下文用\(Suf_S[i]\)表示\(S[i,i+1,\cdots,|S|]\),对\(Suf_T\)同理。并用\(S[l,r]\)表示\(S[l,l+1,\cdots,r]\),对\(T[l,r]\)同理)后缀数组包含两个数组\(rk,sa\)。\(rk[i]\)表示后缀\(Suf_S[i]\)排序后的排名。\(sa[i]\)表示排......
  • OP-TEE学习笔记(一)
    OP-TEE由于工作原因接触过一些使用TEE代替HSM来实现密钥存储、密钥对生成的方案,因此想了解一下开源的TEE方案与TEE供应商提供的方案有什么不同。关于OP-TEEOP-TEE是设计为与在Arm上运行的非安全Linux内核配合使用的一种受信任执行环境(TEE),Cortex-A内核使用TrustZone技术。OP......
  • JVM学习笔记
    1.运行时数据区1.2运行时数据区及线程概述JVM将内存划分为俩种类型的数据区域线程共享:JVM启动时创建,退出时才销毁线程私有:线程创建时创建,线程退出时销毁1.2.1运行时数据区JVM内存布局规定了Java运行过程中内存申请,分配,管理的策略,保证高效运行。不同JVM在内存划分和管理......
  • C# 闲来笔记
    1.Debug.WriteLine、Trace.WriteLine//WriteLineWritePrintDebug.WriteLine("debug调试模式下--在跟踪窗口--输出指定内容:",message);//Trace.WriteTrace.WriteLine("debugreplease模式--在跟踪窗口--下输出指定内容",message);Debug.write()用于调试模式下在输出窗口,输出调......
  • mysql_笔记
    MySQL安装与连接安装MySQL官网下载MySQL选择社区免费版下载安装选择.msi安装包双击安装,安装过程可以无脑下一步MySQL启动/关闭开始菜单搜索cmd,找到命令提示符,然后使用管理员身份打开输入命令开启:netstartmysql80关闭:netstopmysql80注:命令中的mysql80取决于......
  • 【笔记】RedmiBookPro15锐龙板(7840hs)安装ubuntu2204注意事项
    /** 2024-04-17 12:53:52*/1、不要安装ubuntu2004,驱动问题很烦入,尤其是AMD的显卡驱动,不论哪个版本都不要打AMD的官方驱动,经常花屏,卡的完全不能操作,自带的开源驱动就行了,偶尔出现一两道花屏的,不影响使用,而且一会就消失了。如果经常出现在bios里调大显存试试,默认512估计不够,我......
  • 点分树(动态点分治)学习笔记
    1.定义在点分治的基础上加以变化,构造一颗支持快速修改的重构树,称之为点分树2.算法2.1.思路点分治的核心在于通过树的重心来划分联通块,减少合并层数,从而降低时间复杂度所以,我们可以按分治递归的顺序提出一颗树,易知树高至多为logn具体的说,对于每一个找到的重心,将上一次分治......
  • 「笔记」树同构
    目录写在前面树同构定义有根树同构无根树同构树哈希有根树无根树AHU算法例题UOJ#763.树哈希SP7826-TREEISO-TreeIsomorphismP5043【模板】树同构([BJOI2015]树的同构)写在最后写在前面vp的时候用到了于是来学一下。好水。抱歉了AHU,但是树哈希它实在是太好写了。树同......
  • ROS2笔记1--简介及开发环境搭建
    一、ROS2简介1.1、ROS2概述ROS2是第二代的RobotOperatingSystem,ROS1的升级版本,解决了ROS1存在的一些问题。与ROS1相比,Linux版本与ROS2版本的选择也有关系,对应关系如下:ROS2版本Ubuntu版本FoxyUbuntu20.04GalacticUbuntu20.04HumbleUbuntu......
  • 后缀数组学习笔记
    定义后缀从字符串某个位置i到字符串末尾的子串,定义s的第i个字符为第一个元素的后缀为suf(i)。后缀数组把s的每一个后缀按照字典序排序,后缀数组sa[i]表示排名为i的后缀的起始位置的下标。rk[i]数组代表起始位置为i的后缀的排名。rk[]和sa[]是一一对应关系,互为逆运算,可以相互......