题目描述
高斯消元解线性方程
列主元消去法:
依次枚举每一列
(1)找到每一列绝对值最大的数
(2)换到第一行
(3)将该行第一个数变成1
(4)将下面的所有的行的该列都变成0,直至变成上三角矩阵
C++ 代码
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=110;
int n;
const double eps=1e-6; //必须是浮点数:1e-6表示1乘以10的负6次方,1e-6其实相当于x==0,1e-6(也就是0.000001)用来抵消浮点运算中因为误差造成的相等无法判断的情况。表示一个特别小的数字
double a[N][N];
void out()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<=n;j++)printf("%10.2lf",a[i][j]); //将计算过程中的数输出验证步骤
puts("");
}
puts("");
}
int gauss()
{
int c; //列号
int r; //行号
for(c=0,r=0;c<n;c++) //系数矩阵是列和行数一样,所以可以只用一个n来限制
{
int t=c;
//确定出绝对值最大的一行
for(int i=r;i<n;i++) //比较确定列的每一行,即变量是行
{
if(fabs(a[i][c])>fabs(a[t][c])) //fabs表示浮点的绝对值
{
t=i; //确定当前数大的行号
}
}
//该行的第一个系数不能为0
if(fabs(a[t][c])<eps)continue;
for(int i=c;i<=n;i++)swap(a[t][i],a[r][i]);//将确定出来的行与当前的第一行的每一列互换
for(int i=n;i>=c;i--)a[r][i]/=a[r][c]; //将当前第一行的第一列系数计算为1
//将下面所有行的该列都变成0----为了转化成上三角矩阵
for(int i=r+1;i<n;i++) //从下一行开始循环比较
{
if(fabs(a[i][c])>eps)//
{
for(int j=n;j>=c;j--)
a[i][j]-=a[r][j]*a[i][c];//以最上面的那一行作为乘数,与当前行相减(因为第一行的第一个数已经化为了1,所以a[i][c]/a[i][r])
}
}
// out();
r++;
}
//剩下的方程个数小于n,则不是有唯一解
if(r<n)
{
for(int i=r;i<n;i++)
{
if(fabs(a[i][n])>eps) //出现0=非零
return 2; //无解
}
return 1;//否则有无穷多个解
}
for(int i=n-1;i>=0;i--)
{
for(int j=i+1;j<n;j++)
a[i][n]-=a[i][j]*a[j][n];
}
return 0;//有唯一解
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
cin>>a[i][j];
}
int t=gauss();
if(t==0)
{
for(int i=0;i<n;i++)printf("%.2lf\n",a[i][n]);
}
else if(t==1)puts("Infinite group solutions");
else puts("No solution");
return 0;
}