首页 > 其他分享 >高斯消元学习笔记

高斯消元学习笔记

时间:2024-05-26 17:23:50浏览次数:22  
标签:end int 矩阵 笔记 学习 cdots bmatrix 高斯消 vdots

高斯消元学习笔记

其实这个主题能够复活主要还是粘了 \(\text{LGV}\) 引理的光,不然我还不知道高斯消元其实不光能求解线性方程组。

求解线性方程组

这个只能说是典中典了,我不相信没有一个人的高斯消元不是从这里开始的。

我们考虑求解线性方程组的本质:将每一个式子所有未知数前都有系数转化成每一个式子只有一个未知数前有系数。那么我们不妨用矩阵来表示这样的关系。

对于线性方程组

\[\left\{\begin{matrix}a_{1,1}x_1+a_{1,2}x_2+\cdots+a_{1,n}x_n=b_1\\a_{2,1}x_1+a_{2,2}x_2+\cdots+a_{2,n}x_n=b_2\\\vdots\\a_{n,1}x_1+a_{n,2}x_2+\cdots+a_{n,n}x_n=b_n\end{matrix}\right. \]

我们将其写成

\[\begin{bmatrix}a_{1,1}&a_{1,2}&\cdots&a_{1,n}&b_1\\a_{2,1}&a_{2,2}&\cdots&a_{2,n}&b_2\\\vdots&\vdots&\ddots&\vdots&\vdots\\a_{n,1}&a_{2,n}&\cdots&a_{n,n}&b_n\end{bmatrix} \]

的形式,接着我们考虑消元,为了让整个矩阵最后呈现出

\[\begin{bmatrix}1&0&\cdots&0&b_1\\0&1&\cdots&0&b_2\\\vdots&\vdots&\ddots&\vdots&\vdots\\0&0&\cdots&1&b_n\end{bmatrix} \]

的形式,我们需要:

  1. 对于枚举到的每一行,将当前行对应的未知数前的系数变为 \(1\)。
  2. 将其他行对应此时的未知数前的系数变为 \(0\)。

最后从下往上,将每个未知数的值回代,求出每个未知数的解。

对于无解或无穷解的判断,主要在于全 \(0\) 行。如果出现 \(\begin{bmatrix}0&0&\cdots&0&0\end{bmatrix}\) 的行,那么说明有一个未知数可以取任意实数,因此有无穷解。如果出现 \(\begin{bmatrix}0&0&\cdots&0&b\end{bmatrix}\) 且 \(b\ne 0\),那么说明 \(0\ne 0\),那么此时整个方程组无解。复杂度是标准 \(O(n^3)\) 的。

代码

int gauss(){
	int c,r;
	for(c=1,r=1;c<=n;c++){
		int t=r;
		for(int i=r;i<=n;i++){
			if(fabs(a[i][c])>fabs(a[t][c]))t=i;
		}
		if(fabs(a[t][c])<eps)continue;
		for(int i=c;i<=n+1;i++)swap(a[t][i],a[r][i]);
		for(int i=n+1;i>=c;i--)a[r][i]/=a[r][c];
		for(int i=r+1;i<=n;i++){
			if(fabs(a[i][c])>eps){
				for(int j=n+1;j>=c;j--)a[i][j]-=a[r][j]*a[i][c];
			}
		}
		r++;//消元
	}
	if(r<=n){
		for(int i=r;i<=n;i++){
			if(fabs(a[i][n+1])>eps)return 2;//方程无解
		}
		return 1;//方程有无穷多组解
	}
	for(int i=n;i>=1;i--){
		for(int j=i+1;j<=n;j++)a[i][n+1]-=a[i][j]*a[j][n+1];
	} 
	return 0;//方程有唯一解
}

求解矩阵逆元

学过矩阵快速幂的都知道,矩阵的单位元 \(I\) 形如:

\[\begin{bmatrix}1&0&\cdots&0\\0&1&\cdots&0\\\vdots&\vdots&\ddots&\vdots\\0&0&\cdots&1\end{bmatrix} \]

参考整数逆元的定义:如果 \(aa^{-1}\equiv1\pmod p\),则称 \(a^{-1}\) 是 \(a\) 在模 \(p\) 意义下的逆元,更一般的,如果没有模 \(p\),那么 \(a^{-1}=\frac{1}{a}\)。

那么对于一个矩阵 \(A\),是否存在它的逆元 \(A^{-1}\),使得 \(AA^{-1}\equiv I\pmod p\) 或是 \(AA^{-1}=I\) 呢?答案是肯定的,但是矩阵的逆显然没有整数那么好求,于是我们考虑这样一个矩阵:

\[A|I=\begin{bmatrix}a_{1,1}&a_{1,2}&\cdots&a_{1,n}&1&0&\cdots&0\\a_{2,1}&a_{2,2}&\cdots&a_{2,n}&0&1&\cdots&0\\\vdots&\vdots&\ddots&\vdots&\vdots&\vdots&\ddots&\vdots\\a_{n,1}&a_{n,2}&\cdots&a_{n,n}&0&0&\cdots&1\end{bmatrix} \]

那么我们对左边的 \(A\) 进行消元,本质上就是将其变为单位元 \(I\),也就是除以 \(A\),那么矩阵将会变成 \(I|A^{-1}\),此时右边的部分就是我们需要求的逆元了。

但是和整数逆元一样,矩阵在有些时候也没有逆元,比如不能成功除以 \(A\) 的时候,也就是消元失败的时候,当且仅当 \(\exists i,a_{i,i}=0\),此时除数为 \(0\),消元自然失败。因为和高斯消元的思路一致,复杂度是标准 \(O(n^3)\) 的。

我们可以考虑矩阵求逆和求解线性方程组的关系,不难发现,如果令

\[A=\begin{bmatrix}a_{1,1}&a_{1,2}&\cdots&a_{1,n}\\a_{2,1}&a_{2,2}&\cdots&a_{2,n}\\\vdots&\vdots&\ddots&\vdots\\a_{n,1}&a_{n,2}&\cdots&a_{n,n}\end{bmatrix},B=\begin{bmatrix}b_1\\b_2\\\vdots\\b_n\end{bmatrix},X=\begin{bmatrix}x_1\\x_2\\\vdots\\x_n\end{bmatrix} \]

那么有 \(AX=B\),即 \(X=A^{-1}B\)。由此我们发现,利用矩阵逆元我们也能求解出有解方程的正确解,但当矩阵没有逆元时,我们不能具体判断是无解还是有无穷多组解。

代码

int gauss(){
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            if(fabs(A[j][i])<=eps)continue;
            for(int k=i;k<=(n<<1);k++)swap(A[i][k],A[j][k]);
            break;
        }
        if(fabs(A[i][i])<=eps)return 1;
        for(int j=(n<<1);j>=i;j--)A[i][j]/=A[i][i];
        for(int j=1;j<=n;j++){
            if(i==j)continue;
            for(int k=(n<<1);k>=i;k--)A[j][k]-=A[j][i]*A[i][k];
        }
        
    }
    return 0;
}

求解行列式

对于一个矩阵 \(A\) 的行列式,我们记为 \(\text{det}(A)\) 或 \(|A|\)。对于行列式有如下定义:

对于矩阵

\[A=\begin{bmatrix}a_{1,1}&a_{1,2}&\cdots&a_{1,n}\\a_{2,1}&a_{2,2}&\cdots&a_{2,n}\\\vdots&\vdots&\ddots&\vdots\\a_{n,1}&a_{2,n}&\cdots&a_{n,n}\end{bmatrix} \]

\[|A|=\sum_{p}(-1)^{r(p)}\prod_{i=1}^na_{i,p_i} \]

其中 \(p\) 是 \(1\) 到 \(n\) 的排列,\(r(p)\) 是排列 \(p\) 中逆序对的个数。对于暴力搜索而言复杂度是 \(O(n!n\log n)\) 的。而对于行列式又有以下几个容易证得的性质:

  1. 如果矩阵 \(A\) 是一个上三角矩阵,即 \(\forall i>j,a_{i,j}=0\),那么 \(|A|=\prod_{i=1}^{n}a_{i,i}\)。
  2. 如果矩阵 \(A\) 的某一行同时乘上一个常数 \(k\) 得到矩阵 \(A'\),那么 \(|A'|=k|A|\)。
  3. 矩阵 \(A\) 的行列式与矩阵 \(A\) 的转置的行列式相等,即 \(|A|=|A^T|\)。
  4. 如果矩阵 \(A\) 的任意两行互换后得到矩阵 \(A'\),那么 \(|A'|=-|A|\)。
  5. 如果矩阵 \(A\) 的其中一行加上另外一行得到矩阵 \(A'\),那么 \(|A'|=|A|\)。

不难发现消元的过程符合性质 \(2,4,5\),而消元后的矩阵符合性质 \(1\),因此可以利用高斯消元求解。复杂度是 \(O(n^3)\) 的。

我们可以考虑行列式和求解线性方程组的关系,根据 \(\text{Cramar}\) 法则可以得知:

给定一个 \(n\) 元线性方程组,其未知数分别记作 \(x_1,x_2,\cdots,x_n\)。

设其矩阵表示形式为 \(AX=B\)​,其中 \(A\) 为该方程组的增广矩阵,\(X\) 为由未知数组成的向量,\(B\) 为由常数项组成的向量,\(A_i\) 为 \(A\) 中的第 \(i\) 列被 \(B\) 取代后的矩阵,若 \(|A|\ne 0\),则 \(x_i=\frac{|A_i|}{|A|}\);否则该方程组无解。

由此,我们看出求解线性方程组也可以通过这样的方式完成。但是复杂度要更差。

代码

double gauss(){
    double res=1;
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            if(fabs(A[j][i])<=eps)continue;
            for(int k=i;k<=n;k++)swap(A[i][k],A[j][k]);
            if(i!=j)res=-res;
            break;
        }
        if(fabs(A[i][i])<=eps)return 0;
        for(int j=i+1;j<=n;j++){
            for(int k=n;k>=i;k--)A[j][k]-=A[j][i]/A[i][i]*A[i][k];
        }
    }
    for(int i=1;i<=n;i++)res*=A[i][i];
    return res;
}
//下面提供一种模数不为质数的写法
ll gauss(){
    ll res=1;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            while(a[i][i]){
                ll div=a[j][i]/a[i][i];
                for(int k=i;k<=n;k++)a[j][k]=(a[j][k]-div*a[i][k])%P;
                for(int k=i;k<=n;k++)swap(a[i][k],a[j][k]);
                res=-res;
            }
            for(int k=i;k<=n;k++)swap(a[i][k],a[j][k]);
            res=-res;
        }
    }
    for(int i=1;i<=n;i++)res=res*a[i][i]%P;
    return res;
}

标签:end,int,矩阵,笔记,学习,cdots,bmatrix,高斯消,vdots
From: https://www.cnblogs.com/DycBlog/p/18213986

相关文章

  • Java学习笔记(二)
    Java学习笔记(二)快捷方法生成psvm>>publicstaticvoidmain(String[]args){}main>>publicstaticvoidmain(String[]args){}sout>>System.out.println();i.sout>>System.out.println(i);i.soutv>>System.out.println("i=&......
  • 排队免单,买单返现,2+1连动营销小程序源码学习使用下载。
    在当下数字化与智能化高速发展的时代,各类创新型的商业模式层出不穷,其中排队免单系统和买单返现系统便是颇具吸引力的两种商业模式。这两种系统不仅提升了消费者的购物体验,还为企业带来了更多的商业机会和收益。本文将详细解析排队免单系统和买单返现系统的运作原理、优势以......
  • 超简单白话文机器学习 - 回归树&树剪枝(含算法介绍,公式,源代码实现以及调包实现)
    1.回归树1.1算法介绍大家看到这篇文章时想必已经对树这个概念已经有基础了,如果不是很了解的朋友可以看看笔者的这篇文章:超简单白话文机器学习-决策树算法全解(含算法介绍,公式,源代码实现以及调包实现)_白话决策树-CSDN博客对于回归树的建立,我们一般使用CART回归树,CART(Clas......
  • 《计算机网络微课堂》3-9 以太网交换机自学习和转发帧的流程
    在上节课中,我们对比了在物理层扩展以太网的集线器,和在数据链路层扩展以太网的交换机。本节课我们介绍以太网交换机自学习和转发帧的流程,以太网交换机工作在数据链路层,当然也包括物理层,需要说明的是目前市场上也有包含网络层部分功能的交换机,称为三层交换机。以太网交换机收到帧......
  • 【精简笔记】JavaScript基础内容大总结
    往期文章目录【精简笔记】JavaScript基础内容第一天【精简笔记】JavaScript基础内容第二天【精简笔记】JavaScript基础内容第三天【精简笔记】JavaScript基础内容第四天【精简笔记】JavaScript基础内容第五天文章目录往期文章目录前言一、JavaScript的书写位置1.......
  • 学习方法--如何写出第一篇论文?
    1.确定论文的题目。题目要具体,有深度,突出算法。2.写论文摘要。要突出本文针对什么重要问题,提出了什么方法,跟已有工作相比,具有什么优势。实验结果表明,达到了什么水准,解决了什么问题。3.写引言。首先讲出本项工作的背景,这个问题的定义,它具有什么重要性。然后介绍对这个问题,现有......
  • LGV 引理学习笔记
    \(\text{LGV}\)引理学习笔记\(\text{LGV}\)引理一般用于求解有向无环图中多条不相交路径的方案数,引理内容如下。引理定义\(w(P)\)指的是路径\(P\)上所有边权的乘积(在路径计数问题中认为所有边权均为\(1\)即可),\(e(A,B)\)指的是\(A\toB\)的所有路径的\(w\)和。对......
  • [学习分享]基于matlab的新安江模型_01_模型介绍与蓄满产流
    写在前面的  最近笔者刚完成水文预报这门课的课程设计,课程设计要求根据课本自行实现新安江模型,完成径流模拟。现在课程设计已经基本全部做完,自己感觉做的也还不错,同时也因为蛮喜欢水文预报这门课的,所以想再对课程设计的整个过程做个整理分享出来,也希望能够帮助到一些困惑于......
  • OOP笔记 —— 多态(Polymorphism)
    多态就是同一个方法的不同实现(即:相同的函数名,不同的函数体)多态的精髓在于父类指针的使用:将子类的地址赋给父类指针,即父类指针指向子类对象注意:用指针去调用成员方法时,通过“->”符号1.虚函数(VirtualFunction)此处的虚函数是指非纯虚函数。定义:非纯虚函数是一个带有virt......
  • 数据结构与算法学习(05)查找(2)索引——BUAA
    文章目录查找(2)——索引介绍索引的基本概念稠密索引非稠密索引——分块索引多级索引查找(2)——索引介绍本文为查找第二部分,主要是整理了本人上课时讲的内容索引的基本概念索引:记录关键字值与记录的存储位置之间的对应关系索引文件:由基本数据与索引表两部分组成的......