线性方程组-高斯消元
高斯消元求解线性方程组
将如下方程组: 消成上三角矩阵: 步骤:
- 枚举主元,找到主元下面系数不是0的一行
- 用变换1,把这一行与主元行交换
- 用变换2,把主元系数变成1
- 用变换3,把主元下面的系数变成0
代码
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cout<<"a["<<x<<"]="<<a[x]<<endl;
#define pr(x) cout<<x<<endl;
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 110;
const double eps=1e-6;
int n;
double a[N][N];
int gauss(){
for(int i=1;i<=n;i++){//枚举行
int cur=i;//当前行
for(int k=i;k<=n;k++){//去找非0行
if (fabs(a[k][i])>eps){//大于0
cur=k;
break;
}
}
if (cur!=i) swap(a[i],a[cur]);//交换两行
if (fabs(a[i][i])<eps) return 0;
for(int j=n+1;j>=i;j--){//枚举列,从后往前
a[i][j]/=a[i][i];//除上第i行的第一个数
//最后第i行的第一个数会变成1
}
for(int k=i+1;k<=n;k++){//将第i行下面的每一行变0
for(int j=n+1;j>=i;j--){//从后往前枚举
a[k][j]-=a[k][i]*a[i][j];//减去第k行的第1个元素*第i行的第j个元素
}
}
}
for(int i=n-1;i>=1;i--)//从倒数第2行开始
for(int j=i+1;j<=n;j++)
a[i][n+1]-=a[i][j]*a[j][n+1];
return 1;
}
int main() {
// IOS;
#ifndef ONLINE_JUDGE
freopen("/Users/houyunfei/CLionProjects/MyCppWorkSpace/test.in", "r", stdin);
freopen("/Users/houyunfei/CLionProjects/MyCppWorkSpace/test.out", "w", stdout);
#endif
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)
cin>>a[i][j];
if (gauss()){
for(int i=1;i<=n;i++)
printf("%.2lf\n",a[i][n+1]);
}else{
pr("No Solution")
}
return 0;
}
高斯约旦消元法
思路:每轮循环,主元所在行不变,所在列消成0
代码
int Gauss_Jordan(){
for(int i=1;i<=n;i++) {//枚举行
int cur = i;//当前行
for (int k = i; k <= n; k++) {//去找非0行
if (fabs(a[k][i]) > eps) {//大于0
cur = k;
break;
}
}
if (cur != i) swap(a[i], a[cur]);//交换两行
if (fabs(a[i][i]) < eps) return 0;
//对角化,主元所在行不变,所在列消成0
for(int k=1;k<=n;k++){
if (k==i) continue;
double t=a[k][i]/a[i][i];
for(int j=i;j<=n+1;j++){
a[k][j]-=t*a[i][j];
}
}
}
for(int i=1;i<=n;i++)
a[i][n+1]/=a[i][i];
return 1;
}