【矩阵乘法与高斯消元】
目录
一. 概念引入
1.高斯消元的概念方法
根据数学知识可知:
然后我们尝试解方程组:
得出解的情况:
【具体过程模拟】
我们首先确定一个方程组作为例子。
x-2y+3z=6
4x-5y+6z=12
7x-8y+10z=21
先将它转化为矩阵(3*3的系数矩阵,加上最后一列之后是增广矩阵):
1 -2 3 6
4 -5 6 12
7 -8 10 21
解决这个方程组,我们会希望它变成如下形式(单位矩阵):
1 0 0 a
0 1 0 b
0 0 1 c
这样就可以表示为x=a,y=b,z=cx=a,y=b,z=cx=a,y=b,z=c。
我们使用高斯消元,一步一步将每个未知数约去。
这种方法是以列为单位消去的。首先我们将第一列转化为1 0 0的形式。
往往是将这个系数绝对值最大的方程转移到当前处理的这一行,可以减小误差。
所以我们先将矩阵变成这样:
7 -8 10 21
4 -5 6 12
1 -2 3 6
然后将正在处理的方程式化简,让正被处理的系数化1:
1 -8/7 10/7 3
4 -5 6 12
1 -2 3 6
然后使用加减法将第二个与第三个方程组的第一个系数化0:
1 -8/7 10/7 3
0 -3/7 2/7 0
0 -6/7 11/7 3
然后这时候第一列就被化简完成。
同理我们化去第二行与第三行,步骤如下:
1.化简第二行
1 -8/7 10/7 3
0 1 -2/3 0
0 -6/7 11/7 3
2.用第一行减第二行×(-8/7),第三行减第二行×(-6/7)
1 0 2/3 3
0 1 -2/3 0
0 0 1 3
3.第三行已经为1,直接用第一行减去第三行×2/3,第二行减去第三行×(-2/3)
1 0 0 1
0 1 0 2
0 0 1 3
最后我们就得到了一组解x=1,y=2,y=3x=1,y=2,y=3x=1,y=2,y=3。
【具体代码实现】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<deque>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
/*【p3389】高斯消元模板:求解线性方程组 */
void reads(int &x){ //读入优化(正负整数)
int fx=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')fx=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=fx; //正负号
}
const double EPS=1E-8;
double A[110][110]; //【一定要用非整形!】
int main(){
int n; reads(n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
scanf("%lf",&A[i][j]); //读入系数
scanf("%lf",&A[i][n]); //读入值(变为增广矩阵)
}
for(int i=0;i<n;i++){
int max_one=i;
for(int j=i;j<n;j++) //选择一个在当前列上【系数绝对值最大的】调换过来
if(f