前置知识
高斯-约旦消元
和高斯消元一样,高斯-约旦消元也是通过加减消元来化简方程。两者之间的不同在于,高斯-约旦消元会将系数矩阵消成形如
A
′
=
[
a
1
,
1
′
b
1
′
a
2
,
2
′
b
2
′
⋱
⋮
a
n
,
n
′
b
n
′
]
A'=\begin{bmatrix}a_{1,1}'&&&&b_1'\\&a_{2,2}'&&&b_2'\\&&\ddots&&\vdots\\&&&a_{n,n}'&b_n'\end{bmatrix}
A′=
a1,1′a2,2′⋱an,n′b1′b2′⋮bn′
的形式。
一般来说,
a
i
,
i
′
=
1
a_{i,i}'=1
ai,i′=1,此时
x
i
=
b
i
′
x_i=b_i'
xi=bi′ 即为一组解。
特殊情况下,
a
i
,
i
′
=
0
a_{i,i}'=0
ai,i′=0,那么解的情况也很好确定,先判无解,再判多解,不多做赘述。
接下来简述高斯-约旦消元的过程。
首先我们利用
(
1
)
(1)
(1) 式进行消元,先通过除以
a
1
,
1
a_{1,1}
a1,1 将
a
1
,
1
a_{1,1}
a1,1 化为
1
1
1,其他和基本高斯消元相同。
接着对于
(
2
)
(2)
(2) 式,同样先将
a
2
,
2
a_{2,2}
a2,2 化为
1
1
1,此时
a
1
,
0
=
0
a_{1,0}=0
a1,0=0,对
(
1
)
(1)
(1) 式的
a
1
,
1
a_{1,1}
a1,1 没有影响,故可同理对
(
1
)
(1)
(1) 式消元。
同理,消元后必得如上系数矩阵。
优化
同理,交换至最大再消元。
算法参数
- 时间复杂度: O ( n 3 ) O(n^3) O(n3)
- 空间复杂度: O ( n 2 ) O(n^2) O(n2)
实现代码
#include<bits/stdc++.h>
using namespace std;
const long double eps=1e-10;
int n,cur=1;
long double a[110][110];
int main(){
cin>>n;
for (int i=1;i<=n;i++) for (int j=1;j<=n+1;j++) cin>>a[i][j];
for (int i=1;i<=n;i++){
int idx=cur;
for (int j=cur;j<=n;j++) if (fabs(a[j][i])>fabs(a[idx][i])) idx=j;
if (fabs(a[idx][i])>eps) swap(a[cur],a[idx]);
else continue;
for (int j=n+1;j>=i;j--) a[cur][j]/=a[cur][i];
for (int j=1;j<=n;j++) if (j!=cur) for (int k=n+1;k>=i;k--) a[j][k]-=a[j][i]*a[cur][k];
cur++;
}
for (int i=cur;i<=n;i++) if (fabs(a[i][n+1])>eps){cout<<"No solutions";return 0;}
for (int i=1;i<=n;i++) if (fabs(a[i][i])<eps){cout<<"Many solutions";return 0;}
for (int i=1;i<=n;i++) printf("x%d=%.10Lf\n",i,a[i][n+1]/a[i][i]);
return 0;
}