您的位置:首页 > 编程语言 > C语言/C++

按照高等代数的传统解法编写c++程序实现N(N<256)元的线性方程组的求解

2016-09-04 16:29 866 查看
对于c++实现线性方程组的求解问题,前辈已经有太多的好算法。有一本书叫《C数值算法》,里面就详尽的论述了如何求解各种各样的线性方程组。

然而,前辈们的算法,无一例外几乎都是只得出一个解。面对奇异线性方程组,也只是尽量化为非奇异的线性方程组,然后解出一种解。

我笨拙,自己想了一套算法,按照高等代数人工求解线性方程组的步骤,用c++模仿人工步骤解决线性方程组的无解、一解、多解问题,并给出一解或者多解的解向量矩阵。

该程序选择从txt文档读入矩阵,并将结果输入txt文档。

(c++处理数据的难点之一,就是对矩阵的运算,实现过程是比较麻烦的。也就是数值运算的困难之处)

#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;
void solution1(double [][256],int,int,string);
void solution2(double [][256],int,int,string);
int main()
{
int end;
while(true)
{
cout<<"请您先在此程序所在文件目录下建立一个txt文档,文档名格式为xxx.txt"<<endl;
cout<<"并且将您所要求的线性方程组的系数矩阵(或增广矩阵)整齐的输入进去"<<endl;
cout<<"等您完全输入进去并且保存之后,我们再来进行接下来的工作.我等着您哦"<<endl;
system("pause");
cout<<"您回来了?看样子你已经输入完毕了.那我们进行接下来的工作吧"<<endl;
system("pause");
cout<<"请您输入您刚刚创立的txt文档名"<<endl;
string filename;
cin>>filename;
cout<<"开始解线性方程组了哦"<<endl;
int row,column;
double matrix[256][256];
cout<<"请您输入线性方程组的系数矩阵(或者非齐次线性方程组的增广矩阵)的行数和列数"<<endl;
cin>>row;
cin>>column;
ifstream infile;
infile.open(filename.c_str());
if(!infile.is_open())
{
cerr<<"啊哦,出错啦.您是不是把文档名输错啦???哎!没办法啦,关闭程序从头开始吧"<<endl;
}
else
{
for(int i=0;i<row;i++)
{
for(int j=0;j<column;j++)
{
infile>>matrix[i][j];
}
}
}
infile.close();
system("pause");
int linequ;//linequ==linear equations
cout<<"如果该方程组是齐次线性方程组,请您输入1"<<endl;
cout<<"如果该方程组是非齐次线性方程组,请您输入2"<<endl;
cout<<"您输入的是:";
cin>>linequ;
if(linequ==1)
{
solution1(matrix,row,column,filename);
}
if(linequ==2)
{
solution2(matrix,row,column,filename);
}
if(linequ!=1&&linequ!=2)
{
cout<<"不按要求来输入,您不乖,我不要和你玩了"<<endl;
}
system("pause");
cout<<"如果您还想继续求解另一个线性方程组,请输入除666以外的任意整数"<<endl;
cout<<"如果您想结束该程序了,请输入666"<<endl;
cin>>end;
if(end==666)
{
break;
}
}
return 0;
}
//定义求解齐次线性方程组的函数
void solution1(double a[][256],int x,int y,string filename)
{
ofstream outfile;
outfile.open(filename.c_str(),ios::app);
if(!outfile.is_open())
{
cerr<<"啊哦,出错啦!结束程序从头开始吧"<<endl;
}
//输出线性方程组的系数矩阵
cout<<"********************************************************************************"<<endl;
outfile<<endl;
outfile<<"您输入的系数矩阵为:"<<endl;
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
outfile<<a[i][j]<<"\t";
}
outfile<<endl;
}
cout<<"您输入的系数矩阵为:"<<endl;
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
outfile<<"该系数矩阵的初次行阶梯矩阵为:"<<endl;
cout<<"该系数矩阵的初次行阶梯矩阵为:"<<endl;
//将系数矩阵化为行阶梯矩阵
int j,k=0;//j作为循环时矩阵列的变量,k作为循环时矩阵行的变量
for(j=0;j<y;j++)
{
//对矩阵进行冒泡排序,按每列从大到小的顺序排列
for(int i=k;i<x;i++)
{
for(int i=k;i<x;i++)
{
if(fabs(a[i][j])<fabs(a[i+1][j]))
{
for(int j=0;j<y;j++)
{
double temp;
temp=a[i+1][j];
a[i+1][j]=a[i][j];
a[i][j]=temp;
}
}
}
}
//一行一行的化为行阶梯矩阵
for(int i=k+1;i<x;i++)
{
if(a[i][j]!=0)
{
double times;
times=a[i][j]/a[k][j];
for(int j=0;j<y;j++)
{
a[i][j]=a[i][j]-a[k][j]*times;
}
}
else
{
int sum=0;
for(int p=0;p<x;p++)
{
if(a[p][j]==0)
{
sum+=1;
}
}
if(sum==2)
{
int temp=0;
for(int j=0;j<y;j++)
{
if(a[i][j]==0)
{
temp+=1;
}
}
if(temp!=y)
{
double times;
times=a[i][temp]/a[i-1][temp];
for(int j=0;j<y;j++)
{
a[i][j]=a[i][j]-a[k][j]*times;
}
}
}
}
}
k+=1;
}
//输出初次化为的行阶梯矩阵
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
outfile<<a[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
outfile<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl;
cout<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl;
//对初次行阶梯矩阵进行数据调整,减小误差
for(int i=0;i<x;i++)
for(int j=0;j<y;j++)
{
if(fabs(a[i][j])<=1e-10)
{
a[i][j]=0;
}
}
//输出调整之后的行阶梯矩阵
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
outfile<<a[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
//求出系数矩阵的秩并输出
int r=0;
for(int i=0;i<x;i++)
{
int num=0;
for(int j=0;j<y;j++)
{
if(a[i][j]==0)
{
num+=1;
}
}
if(num==y)
{
r+=1;
}
}
r=x-r;
outfile<<"二次行阶梯矩阵的秩为:"<<r<<endl;
cout<<"二次行阶梯矩阵的秩为:"<<r<<endl;
cout<<"********************************************************************************"<<endl;
if(r==y)
{
outfile<<"该线性方程组仅有零解"<<endl;
cout<<"该线性方程组仅有零解"<<endl;
}
if(r<y)
{
outfile<<"该线性方程组有非零解"<<endl;
outfile<<"其解向量构成的矩阵为:"<<endl;
cout<<"该线性方程组有非零解"<<endl;
cout<<"其解向量构成的矩阵为:"<<endl;
//利用行阶梯矩阵求解线性方程组的解向量并输出
int t;
double d[y][r];//该数组存储解向量
for(t=0;t<r;t++)
{
for(int j=0;j<y;j++)
{
d[j][t]=0;
}
d[y-1-t][t]=1;
for(int p=r-1;p>=0;p--)
{
double value=0;
int num=0;
for(int m=0;m<y;m++)
{
if(a[p][m]==0)
{
num+=1;
}
if(a[p][m]!=0)
{
break;
}
}
for(int q=y-1;q>=num+1;q--)
{
value+=a[p][q]*d[q][t];
}
d[num][t]=(-value)/a[p][num];
}
}
for(int i=0;i<y;i++)
{
for(int j=0;j<r;j++)
{
outfile<<d[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<y;i++)
{
for(int j=0;j<r;j++)
{
cout<<d[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
}
outfile.close();
}
//定义求解非齐次线性方程组的函数
void solution2(double a[][256],int x,int y,string filename)
{
ofstream outfile;
outfile.open(filename.c_str(),ios::app);
if(!outfile.is_open())
{
cerr<<"啊哦,出错啦!结束程序从头开始吧"<<endl;
}
//输出线性方程组的增广矩阵
cout<<"********************************************************************************"<<endl;
outfile<<"您输入的增广矩阵为:"<<endl;
cout<<"您输入的增广矩阵为:"<<endl;
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
outfile<<a[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
outfile<<"该增广矩阵的初次行阶梯矩阵为:"<<endl;
cout<<"该增广矩阵的初次行阶梯矩阵为:"<<endl;
//将增广矩阵化为行阶梯矩阵
int j,k=0;//j作为循环时矩阵列的变量,k作为循环时矩阵行的变量
for(j=0;j<y;j++)
{
//对矩阵进行冒泡排序
for(int i=k;i<x;i++)
{
for(int i=k;i<x;i++)
{
if(fabs(a[i][j])<fabs(a[i+1][j]))
{
for(int j=0;j<y;j++)
{
double temp;
temp=a[i+1][j];
a[i+1][j]=a[i][j];
a[i][j]=temp;
}
}
}
}
//一行一行的化为行阶梯矩阵
for(int i=k+1;i<x;i++)
{
if(a[i][j]!=0)
{
double times;
times=a[i][j]/a[k][j];
for(int j=0;j<y;j++)
{
a[i][j]=a[i][j]-a[k][j]*times;
}
}
else
{
int sum=0;
for(int p=0;p<x;p++)
{
if(a[p][j]==0)
{
sum+=1;
}
}
if(sum==2)
{
int temp=0;
for(int j=0;j<y;j++)
{
if(a[i][j]==0)
{
temp+=1;
}
}
if(temp!=y)
{
double times;
times=a[i][temp]/a[i-1][temp];
for(int j=0;j<y;j++)
{
a[i][j]=a[i][j]-a[k][j]*times;
}
}
}
}
}
k+=1;
}
//输出初次化为的行阶梯矩阵
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
outfile<<a[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
outfile<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl;
cout<<"对初次行阶梯矩阵进行数据调整之后的二次行阶梯矩阵为:"<<endl;
//对初次行阶梯矩阵进行数据调整,减小误差
for(int i=0;i<x;i++)
for(int j=0;j<y;j++)
{
if(fabs(a[i][j])<=1e-10)
{
a[i][j]=0;
}
}
//输出调整之后的行阶梯矩阵
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
outfile<<a[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
cout<<a[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
//求出增广矩阵和系数矩阵的秩并输出
int r=0,R=0;
for(int i=0;i<x;i++)
{
int num=0;
for(int j=0;j<y;j++)
{
if(a[i][j]==0)
{
num+=1;
}
}
if(num==y)
{
r+=1;
}
}
for(int i=0;i<x;i++)
{
int num=0;
for(int j=0;j<y-1;j++)
{
if(a[i][j]==0)
{
num+=1;
}
}
if(num==y-1)
{
R+=1;
}
}
r=x-r;
R=x-R;
outfile<<"二次行阶梯矩阵的秩为:"<<r<<endl;
cout<<"二次行阶梯矩阵的秩为:"<<r<<endl;
cout<<"********************************************************************************"<<endl;
if(r<R)
{
outfile<<"该线性方程组无解"<<endl;
cout<<"该线性方程组无解"<<endl;
cout<<"********************************************************************************"<<endl;
}
if(r==R&&r<=y)
{
outfile<<"该线性方程组有多解"<<endl;
outfile<<"其解向量构成的矩阵为:"<<endl;
cout<<"该线性方程组有多解"<<endl;
cout<<"其解向量构成的矩阵为:"<<endl;
//利用行阶梯矩阵求解线性方程组的解向量并输出
int t;
double d[y-1][r];
for(t=0;t<r;t++)
{
for(int j=0;j<y-1;j++)
{
d[j][t]=0;
}
d[y-2-t][t]=1;
for(int p=r-1;p>=0;p--)
{
double value=0;
int num=0;
for(int m=0;m<y-1;m++)
{
if(a[p][m]==0)
{
num+=1;
}
if(a[p][m]!=0)
{
break;
}
}
for(int q=y-2;q>=num+1;q--)
{
value+=a[p][q]*d[q][t];
}
d[num][t]=(-value)/a[p][num];
}
}
for(int i=0;i<y-1;i++)
{
for(int j=0;j<r;j++)
{
outfile<<d[i][j]<<"\t";
}
outfile<<endl;
}
for(int i=0;i<y-1;i++)
{
for(int j=0;j<r;j++)
{
cout<<d[i][j]<<"\t";
}
cout<<endl;
}
cout<<"********************************************************************************"<<endl;
outfile<<"其特解的解向量为:"<<endl;
cout<<"其特解的解向量为:"<<endl;
//利用行阶梯矩阵求解线性方程组的特解
double c[r],e[y-1];
for(int i=0;i<r;i++)
{
c[i]=a[i][y-1];
}
for(int i=0;i<y-1;i++)
{
e[i]=0;
}
e[y-2]=1;
for(int p=r-1;p>=0;p--)
{
double value=0;
int num=0;
for(int m=0;m<y-1;m++)
{
if(a[p][m]==0)
{
num+=1;
}
if(a[p][m]!=0)
{
break;
}
}
for(int q=y-2;q>=num+1;q--)
{
value+=a[p][q]*e[q];
}
e[num]=(c[p]-value)/a[p][num];
}
for(int i=0;i<y-1;i++)
{
outfile<<e[i]<<"\t";
}
for(int i=0;i<y-1;i++)
{
cout<<e[i]<<"\t";
}
cout<<endl;
cout<<"********************************************************************************"<<endl;
}
if(r==R&&r==y)
{
outfile<<"该线性方程组有唯一解"<<endl;
outfile<<"该唯一解的解向量为:"<<endl;
cout<<"该线性方程组有唯一解"<<endl;
cout<<"该唯一解的解向量为:"<<endl;
double m[r],n[y-1];
for(int i=0;i<r;i++)
{
m[i]=a[i][y-2];
}
for(int i=0;i<y-1;i++)
{
n[i]=0;
}
n[y-2]=1;
for(int p=r-1;p>=0;p--)
{
double value=0;
int num=0;
for(int i=0;i<y-1;i++)
{
if(a[p][i]==0)
{
num+=1;
}
if(a[p][i]!=0)
{
break;
}
}
for(int q=y-2;q>=0;q++)
{
value+=n[q]*a[p][q];
}
n[num]=(m[p]-value)/a[p][num];
}
for(int i=0;i<y-1;i++)
{
outfile<<n[i]<<"\t";
}
for(int i=0;i<y-1;i++)
{
cout<<n[i]<<"\t";
}
cout<<endl;
cout<<"********************************************************************************"<<endl;
}
outfile.close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 线性方程组