高斯消元法

一、基本描述

1.高斯消元

主要用来求解线性方程组,也可以求解矩阵的秩,矩阵的逆。在ACM中是一个有力的数学武器。

时间复杂度是O(n3),主要与方程组的个数,未知数的个数有关。

2.什么是线性方程组?

有多个未知数,并且每个未知数的次数均为一次,这样多个未知数组成的方程组为线性方程组。

二、算法实现

       高斯消元法就是手解方程组。

基本原理就是:消元(因为线性方程组次数为1次,不需要考虑降次),然后回代,在得到kx=b这类的式子后,就可以显而易见得到x的解了。

 

举例说明高斯消元法。

假设有如下的方程组:
写成矩阵形式就是: AX=B ,其中:
 ,现对矩阵 A 作初等变换,同时矩阵 B 也作同样的初等变换,则当 A 化为单位矩阵的时候,有:
显而易见,我们得到了方程组的解:  。(Ps.这里的矩阵带T代表是列向量,即x1=1,x2=2,x3=4)
所以, 我们要以一定的策略, 对 A 和 B 施以一系列的初等变换, 当 A 化为单位矩阵的时候,B 就为方程组的解。
三、高斯消元法实现
网上很多模板还强调解出矩阵的上三角形,但是对于一般的题目来说,并没有必要。学会怎么解就好了。
直接例题上板子。
1.bzoj1013 [JSOI2008]球形空间产生器sphere

【题目大意】

给出n维空间中给出n+1个点的坐标,求出球心坐标。

【思路】

令球心坐标为x1,x2...xn,假设当前第i个点坐标为a1,a2...,an,第i+1个点坐标为b1,b2...,bn,则由半径相等可得:

(a1-x1)^2+(a2-x2)^2+...+(an-xn)^2=(b1-x1)^2+(b2-x2)^2+...+(bn-xn)^2

化简可得:

2(a1-b1)x1+2(a2-b2)x2+...+2(an-bn)xn=(a1^2+a2^2+...+an^2-b1^2-b2^2-...-b3^2)

如此可得到n个一元n次方程组,用最简单的高斯消元搞一搞就好了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define maxn 25
 6 using namespace std;
 7 const double eps=1e-6; 
 8 double f[maxn],a[maxn][maxn];
 9 int n;
10 void Gauss(){
11     int i,j,now=1;//now表示处理到第几行
12     for (i=1;i<=n;i++){  //化简为行阶梯型 
13         for (j=now;j<=n;j++){
14             if (fabs(a[j][i])>eps) break;  //当前未知量系数不为0
15         }
16         if (j>n) continue;
17         if (j!=now){
18             for (int k=1;k<=n+1;k++) swap(a[j][k],a[now][k]);
19         }
20         double t=a[now][i];
21         for (int k=1;k<=n+1;k++) a[now][k]/=t;
22         for (int k=1;k<=n;k++){
23             if (k!=now){
24                 t=a[k][i];
25                 for (int l=1;l<=n+1;l++){
26                     a[k][l]-=t*a[now][l];
27                 }
28             }
29         }
30         now++;
31     }
32     return ;
33 }
34 int main(){
35     double x;
36     scanf("%d",&n);
37     for (int i=1;i<=n;i++) scanf("%lf",&f[i]);
38     for (int i=1;i<=n;i++){
39         for (int j=1;j<=n;j++){
40             scanf("%lf",&x);
41             a[i][j]=2*(x-f[j]);
42             a[i][n+1]+=x*x-f[j]*f[j]; 
43         }
44     }
45     Gauss();
46     for (int i=1;i<n;i++) printf("%.3lf ",a[i][n+1]);
47     printf("%.3lf
",a[n][n+1]);
48     return 0;
49 }
原文地址:https://www.cnblogs.com/changer-qyz/p/8446815.html