高斯消去法,列主元高斯法,Doolittle分解法C++程序,解方程组

    《数值分析》课的作业。查看了网上的别人编的程序,一般都先定义了矩阵的行数和列数。

    我这个程序使用了二维动态数组,可以在运行过程中输入行数列数。

//codey by Chen Zhen, 2014/10/17, Beihang University
//使用了二维动态数组

#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;

void Gauss(double **a, double *b,int);//顺序Gauss消去法
void lie_Gauss(double **a, double *b,int);//列主元素Gauss消去法
void Doolittle(double **a, double *b,int);//Doolittle分解法
void print( double **a, double *b,int);//打印方程

void main()
{
	//cout.setf(ios::fixed);
	cout.precision(4);//设置四位有效数字

	//输入矩阵A和b
	int n;
	cout<<"请输入系数矩阵的行数(或列数,列数等于行数):\n";
	cin>>n;
	cin.clear();//这3行代码重置输入
	while(cin.get()!='\n')
		continue;
	cout<<"请输入系数矩阵A:\n";
	
	//要用到二维动态数组
	double **a;
	a=new double *[n];  //申请行的空间
	for (int i=0;i<n;i++)
		a[i]=new double[n];
	for (int i=0;i<n;i++)
	{
		cout<<"第 "<< i+1<<" 行:";
		for (int j=0;j<n;j++)
			while(!(cin>>a[i][j]))
			{
				cin.clear();
				while(cin.get()!='\n')
					continue;
				cout<<"请输入数字";
			}	
		cin.clear();
		while(cin.get()!='\n')
			continue;
	}
	cout<<"请输入矩阵b:\n";
	 double *b=new  double[n];
	for (int j=0;j<n;j++)
		cin>>b[j];
	cin.clear();
	while(cin.get()!='\n')
		continue;

	//将系数矩阵A与矩阵b存储在临时矩阵中,临时矩阵中的元素参与行列变换
	double **temp_a=new double *[n];
	double *temp_b=new double[n];
	for (int i=0;i<n;i++)
		temp_a[i]=new double[n];
	for (int i=0;i<n;i++)
		for (int j=0;j<n;j++)
			temp_a[i][j]=a[i][j];
	for (int i=0;i<n;i++)
		temp_b[i]=b[i];

	//打印方程
	print(( double **)temp_a,temp_b,n);

	//选择解方程方式
	cout<<"请输入你选择的解方程方式(数字):\n";
	cout<<"*************************\n";
	cout<<"1.顺序Gauss法\n2.列主元素高斯法\n";
	cout<<"3.Doolittle分解法\n";
	cout<<"*************************\n";
	int choice;
	while(cin>>choice)
	{
		switch (choice)
		{
		case 1: Gauss(( double **)temp_a,temp_b,n);
			break;
		case 2: lie_Gauss(( double **)temp_a,temp_b,n);
			break;
		case 3:	Doolittle(( double **)temp_a,temp_b,n);
			break;
		case 0: return;
		}
		cout<<"请输入你选择的解方程方式(1-3的数),输入0退出:\n";
	}

	for (int i=0;i<n;i++)
		delete []temp_a[i];
	delete []temp_a;
	delete []temp_b;
	for (int i=0;i<n;i++)
		delete []a[i];
	delete []a;
	delete []b;
}

void Gauss( double **a,double *b,int n)
{
	double mm;
	double *jie=new double[n];
	for (int k=1;k<n;k++)
	{
		if (a[k-1][k-1]==0)
		{
			cout<<"算法失效"<<endl;
			return;
		}
		for (int i=k+1;i<n+1;i++)
		{
			mm=a[i-1][k-1]/a[k-1][k-1];
			for (int j=k+1;j<n+1;j++)
			{
				a[i-1][j-1]=a[i-1][j-1]-mm*a[k-1][j-1];
				
			}
			b[i-1]=b[i-1]-mm*b[k-1];
			for (int j=1;j<k+1;j++)
                a[i-1][j-1]=0;    
		}
		//print((double**)a,b,n);
	}
	if (a[n-1][n-1]==0)
	{
		cout<<"算法失效"<<endl;
		return;
	}
	cout<<"使用顺序Gauss消去法的解为:\n";
	jie[n-1]=b[n-1]/a[n-1][n-1];	
	for (int k=n-1;k>0;k--)
	{
		double temp=0;
		for (int j=k+1;j<n+1;j++)
			temp+=a[k-1][j-1]*jie[j-1];
		jie[k-1]=(b[k-1]-temp)/a[k-1][k-1];	
	}	
	for (int i=0;i<n-1;i++)
		cout<<"x"<<i+1<<" = "<<jie[i]<<endl;
	cout<<"x"<<n<<" = "<<jie[n-1]<<endl;
	cout<<endl;
	delete []jie;
}

void lie_Gauss( double **a,double *b,int n)
{
	for (int k=1;k<n;k++)
	{
		double max=abs(a[k-1][k-1]);
		int lie_hao=k;
		for (int i=k;i<n+1;i++)
			if (abs(a[i-1][k-1])>max)
			{
				max=abs(a[i-1][k-1]);
				lie_hao=i;
			}
		for (int j=k;j<n+1;j++)
		{
			double temp=a[k-1][j-1];
			a[k-1][j-1]=a[lie_hao-1][j-1];
			a[lie_hao-1][j-1]=temp;
		}
		for (int i=k+1;i<n+1;i++)
		{
			double mm=a[i-1][k-1]/a[k-1][k-1];
			for (int j=k+1;j<n+1;j++)
			{
				a[i-1][j-1]=a[i-1][j-1]-mm*a[k-1][j-1];
				
			}
			b[i-1]=b[i-1]-mm*b[k-1];
			for (int j=1;j<k+1;j++)
                a[i-1][j-1]=0;    
		}
	}
	cout<<"使用列主元素Gauss法的解为:\n";
	double *jie=new double[n];
	jie[n-1]=b[n-1]/a[n-1][n-1];	
	for (int k=n-1;k>0;k--)
	{
		double temp=0;
		for (int j=k+1;j<n+1;j++)
			temp+=a[k-1][j-1]*jie[j-1];
		jie[k-1]=(b[k-1]-temp)/a[k-1][k-1];	
	}	
	for (int i=0;i<n-1;i++)
		cout<<"x"<<i+1<<" = "<<jie[i]<<endl;
	cout<<"x"<<n<<" = "<<jie[n-1]<<endl;
	cout<<endl;
	delete []jie;
}

void Doolittle(double **a,double *b,int n)
{
	double **u=new double *[n];
	for (int i=0;i<n;i++)
		u[i]=new double[n];
	double **l=new double *[n];
	for (int i=0;i<n;i++)
		l[i]=new double[n];
	double *jie_x=new double[n];
	double *jie_y=new double[n];
	for (int k=1;k<n+1;k++)
	{
		for (int j=k,i=k+1;j<n+1,i<n+1;j++,i++)
		{
			double sum_1=0;
			for (int t=1;t<k;t++)
			{
				sum_1+=l[k-1][t-1]*u[t-1][j-1];
			}
			u[k-1][j-1]=a[k-1][j-1]-sum_1;
			double sum_2=0;
			for (int t=1;t<k;t++)
			{
				sum_2+=l[i-1][t-1]*u[t-1][k-1];
			}
			l[i-1][k-1]=(a[i-1][k-1]-sum_2)/u[k-1][k-1];
		}
		double sum_1=0;
		for (int t=1;t<k;t++)
		{
			sum_1+=l[k-1][t-1]*u[t-1][n-1];
		}
		u[k-1][n-1]=a[k-1][n-1]-sum_1;
	}
	jie_y[0]=b[0];
	for (int i=2;i<n+1;i++)
	{
		double sum=0;
		for (int t=1;t<i;t++)
			sum+=l[i-1][t-1]*jie_y[t-1];
		jie_y[i-1]=b[i-1]-sum;
	}
	jie_x[n-1]=jie_y[n-1]/u[n-1][n-1];
	for(int i=n-1;i>0;i--)
	{
		double sum=0;
		for (int t=i+1;t<n+1;t++)
			sum+=u[i-1][t-1]*jie_x[t-1];
		jie_x[i-1]=(jie_y[i-1]-sum)/u[i-1][i-1];
	}
	cout<<"使用Doolittle分解法的解为\n";
	for (int i=0;i<n-1;i++)
		cout<<"x"<<i+1<<" = "<<jie_x[i]<<endl;
	cout<<"x"<<n<<" = "<<jie_x[n-1]<<endl;
	cout<<endl;

	delete []jie_x;
	delete []jie_y;
	for (int i=0;i<n;i++)
		delete []u[i];
	delete []u;
	for (int i=0;i<n;i++)
		delete []l[i];
	delete []l;
}

void print(double **a,double *b,int n)
{
	cout<<"方程为:\n";
	cout<<"====================================================\n";
	for (int i=0;i<n;i++)
	{
		for (int j=0;j<n-1;j++)
		{
			cout<<a[i][j]<<" x"<< j+1<<" + ";
		}
		cout<<a[i][n-1]<<" x"<<n<<" = "<<b[i]<<endl;
	}
	cout<<"====================================================\n";
	cout<<endl;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心态与习惯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值