zoukankan      html  css  js  c++  java
  • 高斯消元

    要想学高斯消元,你起码得知道一些矩阵和行列式的基本知识吧。

    如果不会请按Ctrl+W,左转百度一下QwQ


    那么既然你看到了这里,那就说明你已经了解了前置知识

    我们就来说一下高斯消元。

    现在有一组线性不定方程组,要求求出方程的解。

    很明显,我们要将这个方程组转换成它的系数矩阵

    再由这个系数矩阵转换成它的增广矩阵

    消元就在这个增广矩阵中进行

    对于下面这样的一个方程组

    $$
    egin{aligned}
    7x_1&-3x_2-2x_3=7\
    5x_1&-2x_2+7x_3=31\
    3x_1&+2x_2-7x_3=1
    end{aligned}
    $$

    我们首先将其转换为增广矩阵的形式

    就像下面这样

    $$
    egin{bmatrix}
    7&-3&-2&7\5&-2&7&31\3&2&-7&1
    end{bmatrix}
    $$

    我们要想得到最后的解

    就必须要将上面的矩阵转换成下面的矩阵的形式

    $$
    egin{bmatrix}
    1&0&0&a_1\
    0&1&0&a_2\
    0&0&1&a_3
    end{bmatrix}
    $$

    转换成这样的矩阵后,就可以直接得出解。

    下面就是如何转换

    第一次我们要处理第一列,将第一列变成1,0,0的形式,为了防止精度误差(丑陋的C++的锅),每次选取当前处理的这一列中系数绝对值最大的方程,将这个方程与所处理方程替换

    替换完后就把这一行的所有系数全部除以当前位置的值。这样所处理的位置就变成了1。

    像下面这样

    $$
    egin{bmatrix}
    1&-3/7&-2/7&1\
    5&-2&7&31\
    3&2&-7&1
    end{bmatrix}
    $$

    再将其他的所有方程的所有系数都减去这个方程的当前处理的这一列的系数乘以当前处理行的系数

    上面的矩阵在经过上述处理后就变成了下面这样

    $$
    egin{bmatrix}
    1&-3/7&-2/7&1\
    0&1/7&59/7&26\
    0&23/7&-43/7&-2
    end{bmatrix}
    $$

    在接着处理其他的位置到最后一定会变成我们想要的模样

    像这样

    $$
    egin{bmatrix}
    1&0&0&4\
    0&1&0&5\
    0&0&1&3
    end{bmatrix}
    $$

    4,5,3就是这个方程组的解

    代码:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    
    const int MAXN = 107;
    const double EPS = 1e-6;
    
    using namespace std;
    
    int n;
    
    double mat[MAXN][MAXN];
    
    int main() {
    	scanf("%d", &n);
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=n+1; j++) {
    			scanf("%lf", &mat[i][j]);
    		}
    	}
    	for(int i=1; i<=n; i++) {
    		int maxline = i;
    		for(int j=i; j<=n; j++) {
    			if(fabs(mat[j][i]-mat[maxline][i]) <= EPS)
    				maxline = j;
    		}
    		for(int j=1; j<=n+1; j++) {
    			double temp = mat[i][j];
    			mat[i][j] = mat[maxline][j];
    			mat[maxline][j] = temp;
    		}
    		if(fabs(mat[i][i]) <= EPS) {
    			printf("No Solution
    ");
    			return 0;
    		}
    		double temp = mat[i][i];
    		for(int j=1; j<=n+1; j++) {
    			mat[i][j] /= temp;
    		}
    		for(int j=1; j<=n; j++) {
    			if(i != j) {
    				double tmp = mat[j][i];
    				for(int k=i; k<=n+1; k++) {
    					mat[j][k] -= tmp*mat[i][k];
    				}
    			}
    		}
    	}
    	for(int i=1; i<=n; i++) {
    		printf("%.2lf
    ", mat[i][n+1]);
    	}
    	return 0;
    }
    

      

    请各位大大点一下右下角的推荐,(逃

  • 相关阅读:
    PHP 方法整合类 -- 1.根据概率产生随机数 --2.判断手机号归属地及运营商 --3.过滤emoji表情
    PHP 多图下载并打包压缩方法
    PHP 导出excel 精简版
    PHP获取首字母相关方法
    no input file specified 解决办法
    百度地图相关
    经纬度相关方法
    阿里云SSL证书部署至宝塔
    微信入口、生成菜单,公众号授权获取用户信息(unionid)
    超级好用超级简单的支付类库
  • 原文地址:https://www.cnblogs.com/bljfy/p/9185212.html
Copyright © 2011-2022 走看看