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

对于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();
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值