【数据结构与算法】高斯消元法

高斯消元法

数学上,高斯消元法(Gaussian Elimination或译:高斯消去法),是线性代数规划中的一个算法,可用来为线性方程组求解。在许多应用中,我们需要解一个包含n个方程的n元联立方程组:
在这里插入图片描述

其中,n是一个大数。高斯消去法的思路是把n个线性方程构成的n元联立方程组变成一个等价方程组(也就是说,它的解和原来的方程组相同),该方程组有着一个上三角形的系数矩阵,这种矩阵的主对角线下方元素全部为0。

在这里插入图片描述

用矩阵的符号,我们可以把它写成 A x = b = > A ’ x = b ′ {\boldsymbol{A}x=\boldsymbol{b} => \boldsymbol{A’}x=\boldsymbol{b'}} Ax=b=>Ax=b,其中:

在这里插入图片描述

高斯消元法的核心

将一个具有任意系数矩阵的方程组 A \boldsymbol{A} A推导出一个具有上三角系数矩阵的等价方程组 A ′ \boldsymbol{A'} A是高斯消元法需要解决的一个关键问题,这一部分可以通过一系列初等变换(elementary operation)来做到,而所谓的初等变换就是:

  • 交换方程组中两个方程的位置
  • 把一个方程替换为它的非零倍
  • 把一个方程替换为它和另一个方程倍数之间的和或差

高斯消元法的过程

高斯消元法需要经过前向消去反向替换两个步骤。其中,前向消去是利用初等变换来实现从任意系数矩阵方程组变换成具有上三角系数矩阵的等价方程组的过程,反向替换是在前向消去的基础上,从求解 x n {x_{n}} xn(在上三角系数矩阵的等价方程组中,直接利用 b n ′ / a n n ′ {b'_{n}/a'_{nn}} bn/ann得到)开始,将其带回至上一个方程组来求解 x n − 1 x_{n-1} xn1,以此类推,逆向求得所有解的过程。

前向消去的实现

// 输入任意矩阵的引用,返回的布尔变量表示矩阵是否有唯一解
// 经过前向消去后,矩阵将转变为具有上三角系数的矩阵
bool ForwardElimination(vector<vector<double>>& matrix){
	for(int i=0; i<matrix.size()-1; i++){
		// 部分选主元法,从i至n行中,找到n-i+1列中的最大值所在的行
        int pivotrow = i;
		for(int j=i+1; j<matrix.size(); j++){
			if(abs(matrix[j][i]) > abs(matrix[pivotrow][i])){
				pivotrow = j;
			}
		}
        // 由于上三角形的对角线一定不为零,所以如果出现零,则表示解不唯一或无解
        // 同时,这一步可以排除部分主元为零,而出现除零的现象
		if(matrix[pivotrow][i] == 0){
			return false;
		}
        // 将找到的最大值所在的行与第i行进行交换
		for(int k=i; k<matrix.size()+1 && i != pivotrow; k++){
			swap(matrix[i][k], matrix[pivotrow][k]);
		}
        // 将第i+1行到第n行的方程组都减去第i行乘一个数得到的方程组
		for(int j=i+1; j<matrix.size(); j++){
			double temp = matrix[j][i] / matrix[i][i];
			for(int k=i; k<matrix.size()+1; k++){
				matrix[j][k] = matrix[j][k] - matrix[i][k]*temp;
			}
		}
	}
    // 需要单独检测上三角形的对角线上最后一个元素是否为零,如果为零,则表示解不唯一或无解
	if(matrix[matrix.size()-1][matrix.size()-1] == 0){
		return false;
	}
	return true;
}

反向替换的实现

// 函数返回解向量
vector<double> BackSubstitution(vector<vector<double>>& matrix){
	vector<double> solution(matrix.size(), 0);
	for(int i=matrix.size()-1; i>=0; i--){
		for(int j=matrix.size()-1; j>i;j--){
			matrix[i][matrix.size()] -= matrix[i][j]*solution[j];
		}
		solution[i] = matrix[i][matrix.size()] / matrix[i][i];
	}
	return solution;
}

Gauss消元求解方程组

#include<iostream>
#include<vector>
#include<iomanip>
#include<cmath>
using namespace std;

void swap(double& a, double& b){
	double temp = a;
	a = b;
	b = temp;
}

bool ForwardElimination(vector<vector<double>>& matrix){
	for(int i=0; i<matrix.size()-1; i++){
		int pivotrow = i;
		for(int j=i+1; j<matrix.size(); j++){
			if(abs(matrix[j][i]) > abs(matrix[pivotrow][i])){
				pivotrow = j;
			}
		}
		if(matrix[pivotrow][i] == 0){
			return false;
		}
		for(int k=i; k<matrix.size()+1 && i != pivotrow; k++){
			swap(matrix[i][k], matrix[pivotrow][k]);
		}
		for(int j=i+1; j<matrix.size(); j++){
			double temp = matrix[j][i] / matrix[i][i];
			for(int k=i; k<matrix.size()+1; k++){
				matrix[j][k] = matrix[j][k] - matrix[i][k]*temp;
			}
		}
	}
	if(matrix[matrix.size()-1][matrix.size()-1] == 0){
		return false;
	}
	return true;
}

vector<double> BackSubstitution(vector<vector<double>>& matrix){
	vector<double> solution(matrix.size(), 0);
	for(int i=matrix.size()-1; i>=0; i--){
		for(int j=matrix.size()-1; j>i;j--){
			matrix[i][matrix.size()] -= matrix[i][j]*solution[j];
		}
		solution[i] = matrix[i][matrix.size()] / matrix[i][i];
	}
	return solution;
}

int main()
{
	int n;
	cin >> n;
	vector<vector<double>> matrix(n, vector<double>(n+1, 0));
	for(int i=0; i<n; i++){
		for(int j=0; j<n+1; j++){
			cin >> matrix[i][j];
		}
	}		
	bool onlyS = ForwardElimination(matrix);
	if(onlyS){
		vector<double> solution = BackSubstitution(matrix);
		for(int i=0; i<solution.size(); i++){
			cout << fixed <<setprecision(2) << solution[i] << endl;
		}
	}else{
		cout << "No Solution";
	}
	return 0;
} 
  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 计算机常用数值算法与程序是指在计算机科学领域中,常用于处理数值计算的算法和对应的程序,主要涉及数值分析和数值计算的相关内容。下面是几种常见的数值算法和相应的C程序示例: 1. 近似求解方程:二分法是一种常用的近似求解非线性方程的算法。 ```c #include <stdio.h> double f(double x) { // 定义方程 f(x) = 0 的函数 return x * x - 4; } double bisection(double a, double b, double epsilon) { // 用二分法求解方程 f(x) = 0 的近似解 double c; while ((b - a) >= epsilon) { c = (a + b) / 2; if (f(c) == 0) { break; } else if (f(c) * f(a) < 0) { b = c; } else { a = c; } } return c; } int main() { double a = 0, b = 10, epsilon = 0.001; double result = bisection(a, b, epsilon); printf("Approximate solution: %.3f\n", result); return 0; } ``` 2. 插值计算:拉格朗日插值法是一种常用的多项式插值算法。 ```c #include <stdio.h> double interpolate(double x[], double y[], int n, double val) { double result = 0; for (int i = 0; i < n; i++) { double term = 1; for (int j = 0; j < n; j++) { if (j != i) { term *= (val - x[j]) / (x[i] - x[j]); } } result += term * y[i]; } return result; } int main() { double x[] = {0, 1, 2, 3, 4}; double y[] = {1, 4, 9, 16, 25}; int n = sizeof(x) / sizeof(x[0]); double val = 2.5; double result = interpolate(x, y, n, val); printf("Interpolated value at %.1f: %.1f\n", val, result); return 0; } ``` 3. 数值积分:梯形法则是一种常用的数值积分算法。 ```c #include <stdio.h> double f(double x) { // 定义被积函数 f(x) return x * x; } double trapezoid(double a, double b, int n) { double h = (b - a) / n; double result = 0.5 * (f(a) + f(b)); for (int i = 1; i < n; i++) { double x = a + i * h; result += f(x); } result *= h; return result; } int main() { double a = 0, b = 2; int n = 10; double result = trapezoid(a, b, n); printf("Approximate integral: %.2f\n", result); return 0; } ``` 通过上述示例,可以看出计算机常用数值算法与程序是将数学算法转化为计算机可执行的代码,以实现数值计算和数值分析的目的。这些算法和程序在科学计算、工程领域和计算机图形学等领域有着广泛的应用。 ### 回答2: 计算机常用的数值算法与程序是指在计算机科学和数学领域中常用的一些算法和程序,用于解决数值计算问题。 数值算法是指在计算过程中,用数字近似的方式处理实际存在的数值问题的方法。常用的数值算法包括数值积分、求解线性方程组、非线性方程求解和数值优化等。这些算法可以帮助我们在计算机中进行高精度、高效率的数值计算。 数值算法在计算机中的实现通常需要使用编程语言来编写相应的程序。C语言是一种广泛使用的编程语言,其简洁且高效的特性使其成为很多数值算法程序的首选语言。通过使用C语言编写数值算法程序,可以将算法的数学公式转化为计算机可以理解和执行的指令,从而实现具体的数值计算操作。 在C语言中,我们可以利用基本的数学运算、控制结构和数据结构来实现数值算法。例如,可以使用循环和递归来迭代计算数值积分的近似值,或者使用高斯消元法和迭代法来求解线性方程组的解。 除了常用的数值算法,计算机常用的数值程序还包括数值计算库的应用。数值计算库是一组预先实现了各种数值算法的函数和常量,可以供开发者在自己的程序中调用和使用。常见的数值计算库包括GNU Scientific Library (GSL)和Numpy等。通过使用这些数值计算库,我们可以更加方便地实现各种复杂的数值计算操作,提高算法的精度和效率。 综上所述,计算机常用的数值算法与程序是通过使用数值算法和编程语言来实现数值计算问题的解决方案。这些算法和程序可以帮助我们进行高精度、高效率的数值计算,推动科学技术的发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值