• [算法]高斯消元


    前言

    今天被推到洛谷的高斯消元模板
    打了一下,并补一篇博客

    复杂度

    其实是个很暴力的算法
    (Theta(n^3))

    算法讲解

    参照小学数学知识,我们知道有两种消元的方法:加减消元,带入消元
    貌似计算机实现带入消元貌似有点复杂
    所以我们选择加减消元,并且用矩阵存储式子
    栗子:
    (left{ egin{matrix} x + 2y + 3z = 0\ 4x + 5y + 6z = 0\ 7x + 8y + 9z = 0 end{matrix} ight.)
    我们将它转换成
    (left{ egin{matrix} 1 & 2 & 3 & | & 0\ 4 & 5 & 6 & | & 0\ 7 & 8 & 9 & | & 0 end{matrix} ight})
    即第n个式子的第n+1项为该式子的常数项
    但是选择哪个式子来消其他式子的元呢?
    为了使误差最小,我们选择要消去的项系数最大的式子。
    证明:想一下,我们显然希望剩下的式子系数更大,于是就要选择“要消去的项系数最大的式子”
    假设我们要消第i项,我们珂以把该式换到第i行(方便操作)
    然后消去其他项,得到结果
    最后从最后一个式子开始,一个一个往前带入,解除其他变量的值
    技巧:在处理时,把要消的那个式子全部除以自己那项

    代码

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long 
    #define ld long double
    
    ll read(){
    	ll x = 0; int zf = 1; char ch = ' ';
    	while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if (ch == '-') zf = -1, ch = getchar();
    	while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    
    ld mat[105][106];
    ld res[105];
    
    bool guass(int n){
    	int _max;
    	for (int i = 0; i < n; ++i){
    		_max = i;
    		for (int j = i + 1; j < n; ++j)
    			if (mat[_max][i] < mat[j][i]) _max = j;
    		std::swap(mat[_max], mat[i]);
    		ld tmp = mat[i][i];
    		if (fabs(tmp) < 1e-8)
    			return 0;
    		for (int j = i; j <= n; ++j)
    			mat[i][j] /= tmp;
    		for (int j = i + 1; j < n; ++j){
    			tmp = mat[j][i];
    			for (int k = i; k <= n; ++k)
    				mat[j][k] -= mat[i][k] * tmp;
    		}
    	}
    	res[n - 1] = mat[n - 1][n];
    	for (int i = n - 2; i >= 0; --i){
    		res[i] = mat[i][n];
    		for (int j = i + 1; j < n; ++j)
    			res[i] -= res[j] * mat[i][j];
    	}
    	return 1;
    }
    
    int main(){
    	int n = read();
    	for (int i = 0; i < n; ++i)
    		for (int j = 0; j <= n; ++j)
    			mat[i][j] = read();
    	if (guass(n)){
    		for (int i = 0; i < n; ++i)
    			printf("%.2Lf
    ", res[i]);
    	}
    	else
    		printf("No Solution");
    	return 0;
    }
    
  • 相关阅读:
    利用LibreOffice进行WORD转PDF
    SpringBoot实践
    Solr学习笔记(一)
    HashMap原理(转)
    PDF.js展示本地文件
    设计模式之代理模式
    (一)DUBBO基本学习
    如何架构一个框架
    冒泡排序
    js 函数传数组参数
  • 原文地址:https://www.cnblogs.com/linzhengmin/p/10991617.html
Copyright © 2020-2023  润新知