c 解线性方程组的几种方法

合集下载

C语言LU分解法实现解线性方程组

C语言LU分解法实现解线性方程组
C
#include <stdio.h>
#include <stdlib.h>
//LU分解法实现解线性方程组
double sumU(double L[5][5] ,double U[5][5], int i, int j ){
double sU = 0.0;
for (int k = 1; k <= i-1 ; k++)
U[i-1][j-1] = a[i-1][j-1] - sumU(L,U,i,j);
if(j+1 <= n) L[j][i-1] = (a[j][i-1] - sumL(L,U,j+1,i))/U[i-1][i-1];//i变j+1,j变i
}
}
//输出U
printf("U:\n");
for (int i = 1; i <= n; i++)
{
sU += L[i-1][k-1] * U[k-1][j-1];
}
return sU;
}//计算求和1
double sumL(double L[5][5] ,double U[5][5], int i, int j ){
double sL = 0.0;
for (int k = 0; k <= j-1; k++)
printf("%f\t",L[i-1][j-1]);
}
printf("\n");
}
//由Ly=b求y
double y[5] = {0.0};
y[0] = b[0];//y(1) = b(1);

线性方程组的求解方法

线性方程组的求解方法

线性方程组的求解方法线性方程组是数学中的基础概念,广泛应用于各个领域,如物理、经济学、工程学等。

解决线性方程组的问题,对于推动科学技术的发展和解决实际问题具有重要意义。

本文将介绍几种常见的线性方程组的求解方法,包括高斯消元法、矩阵法和迭代法。

一、高斯消元法高斯消元法是求解线性方程组的经典方法之一。

它的基本思想是通过一系列的行变换将方程组化为阶梯形或行最简形,从而得到方程组的解。

首先,将线性方程组写成增广矩阵的形式,其中增广矩阵是由系数矩阵和常数向量组成的。

然后,通过行变换将增广矩阵化为阶梯形或行最简形。

最后,通过回代法求解得到方程组的解。

高斯消元法的优点是简单易懂,容易实现。

但是,当方程组的规模较大时,计算量会很大,效率较低。

二、矩阵法矩阵法是求解线性方程组的另一种常见方法。

它的基本思想是通过矩阵运算将方程组化为矩阵的乘法形式,从而得到方程组的解。

首先,将线性方程组写成矩阵的形式,其中矩阵是由系数矩阵和常数向量组成的。

然后,通过矩阵运算将方程组化为矩阵的乘法形式。

最后,通过求逆矩阵或伴随矩阵求解得到方程组的解。

矩阵法的优点是计算效率高,适用于方程组规模较大的情况。

但是,对于奇异矩阵或非方阵的情况,矩阵法无法求解。

三、迭代法迭代法是求解线性方程组的一种近似解法。

它的基本思想是通过迭代计算逐步逼近方程组的解。

首先,将线性方程组写成矩阵的形式,其中矩阵是由系数矩阵和常数向量组成的。

然后,选择一个初始解,通过迭代计算逐步逼近方程组的解。

最后,通过设定一个误差限,当迭代结果满足误差限时停止计算。

迭代法的优点是计算过程简单,适用于方程组规模较大的情况。

但是,迭代法的收敛性与初始解的选择有关,有时可能无法收敛或收敛速度较慢。

综上所述,线性方程组的求解方法有高斯消元法、矩阵法和迭代法等。

每种方法都有其适用的场景和特点,选择合适的方法可以提高计算效率和解决实际问题的准确性。

在实际应用中,根据问题的具体情况选择合适的方法进行求解,能够更好地推动科学技术的发展和解决实际问题。

线性方程组的数值算法C语言实现(附代码)

线性方程组的数值算法C语言实现(附代码)

线性方程组AX=B 的数值计算方法实验一、 实验描述:随着科学技术的发展,线性代数作为高等数学的一个重要组成部分,在科学实践中得到广泛的应用。

本实验的通过C 语言的算法设计以及编程,来实现高斯消元法、三角分解法和解线性方程组的迭代法(雅可比迭代法和高斯-赛德尔迭代法),对指定方程组进行求解。

二、 实验原理:1、高斯消去法:运用高斯消去法解方程组,通常会用到初等变换,以此来得到与原系数矩阵等价的系数矩阵,达到消元的目的。

初等变换有三种:(a)、(交换变换)对调方程组两行;(b)、用非零常数乘以方程组的某一行;(c)、将方程组的某一行乘以一个非零常数,再加到另一行。

通常利用(c),即用一个方程乘以一个常数,再减去另一个方程来置换另一个方程。

在方程组的增广矩阵中用类似的变换,可以化简系数矩阵,求出其中一个解,然后利用回代法,就可以解出所有的解。

2、选主元:若在解方程组过程中,系数矩阵上的对角元素为零的话,会导致解出的结果不正确。

所以在解方程组过程中要避免此种情况的出现,这就需要选择行的判定条件。

经过行变换,使矩阵对角元素均不为零。

这个过程称为选主元。

选主元分平凡选主元和偏序选主元两种。

平凡选主元:如果()0p pp a ≠,不交换行;如果()0p pp a =,寻找第p 行下满足()0p pp a ≠的第一行,设行数为k ,然后交换第k 行和第p 行。

这样新主元就是非零主元。

偏序选主元:为了减小误差的传播,偏序选主元策略首先检查位于主对角线或主对角线下方第p 列的所有元素,确定行k ,它的元素绝对值最大。

然后如果k p >,则交换第k 行和第p 行。

通常用偏序选主元,可以减小计算误差。

3、三角分解法:由于求解上三角或下三角线性方程组很容易所以在解线性方程组时,可将系数矩阵分解为下三角矩阵和上三角矩阵。

其中下三角矩阵的主对角线为1,上三角矩阵的对角线元素非零。

有如下定理:如果非奇异矩阵A 可表示为下三角矩阵L 和上三角矩阵U 的乘积: A LU = (1) 则A 存在一个三角分解。

线性方程组的解法与应用

线性方程组的解法与应用

线性方程组的解法与应用在数学中,线性方程组是由若干个线性方程组成的方程组,它是研究线性代数的基础。

线性方程组的解法和应用非常广泛,可以用于解决实际生活和工作中的各种问题。

本文将介绍线性方程组的解法以及一些应用案例。

一、线性方程组的解法线性方程组的解法主要有三种:图解法、代入法和消元法。

下面将详细介绍这三种方法。

1. 图解法图解法是线性方程组最直观的解法之一。

通过在坐标系中画出方程组表示的直线或者平面,可以确定方程组的解。

举个例子,考虑一个包含两个未知数的线性方程组:方程一:2x + 3y = 7方程二:4x - y = 1我们可以将方程一化简为 y = (7 - 2x) / 3,方程二化简为 y = 4x - 1。

然后在坐标系中画出这两条直线,它们的交点即为方程组的解。

2. 代入法代入法是一种逐步代入的解法。

通过将已知的某个变量表达式代入到另一个方程中,逐步求解未知数的值。

仍以前述的线性方程组为例,我们可以将方程二中的 y 替换为 (7 - 2x) / 3,代入方程一中:2x + 3((7 - 2x) / 3) = 7通过化简方程,我们可以得到 x 的值,然后再将 x 的值代入到方程二中,求出 y 的值。

3. 消元法消元法是一种通过不断消去未知数来求解方程组的解法。

通过变换或者利用消元的规律,将方程组转化为更简单的形式,从而获得解。

考虑一个包含三个未知数的线性方程组为例:方程一:2x + 3y - z = 10方程二:4x - y + z = 2方程三:x + 2y + z = 3可以使用消元法将这个方程组转化为上三角形式,即方程组的右上方是零。

通过对方程组进行一系列的变换,可以得到转化后的方程组:方程一:2x + 3y - z = 10方程二:-7y + 5z = -18方程三:4y + 5z = -1一旦方程组转化为上三角形式,可以通过回代法依次求解未知数。

二、线性方程组的应用线性方程组的求解方法在现实生活中有着广泛的应用。

高斯方法解线性方程组c程序

高斯方法解线性方程组c程序

高斯消去法和高斯主元消去法解线性方程组:高斯消元法:#include<stdio.h>#include<math.h>main(){int gauss(int n,double a[],double b[]); int i;double a[3][3]={{3,-1,4},{-1,2,-2},{2,-3,-2}}; double b[3]={7,-1,0};if(gauss(3,&a[0][0],b)!=0)for(i=0;i<=2;i++)printf("\nx[%d]=%f\n",i,b[i]);}int gauss(int n,double a[],double b[]) {int i,k,j,p,q;double d,t;for(k=0;k<=n-2;k++){d=a[k*n+k];if(d==0)return(0);for(j=k+1;j<=n-1;j++){p=k*n+j;a[p]=a[p]/d;}b[k]=b[k]/d;for(i=k+1;i<=n-1;i++){for(j=k+1;j<=n-1;j++){p=i*n+j;a[p]=a[p]-a[i*n+k]*a[k*n+j];}b[i]=b[i]-a[i*n+k]*b[k];}}d=a[(n-1)*n+n-1];if(fabs(d)+1.0==1.0){printf("fail\n");return(0);}b[n-1]=b[n-1]/d;for(k=n-2;k>=0;k--){t=0.0;for(j=k+1;j<=n-1;j++)t=t+a[k*n+j]*b[j];b[k]=b[k]-t;}return (1);}⎪⎩⎪⎨⎧=---=-+-=+-0232122743321321321x x x x x x x x x结果:x1=2,x2=1,x3=0.5高斯全选主元法:#include<stdio.h>#include<math.h>#include<stdlib.h>main(){int gauss(int n,double a[],double b[]);int i;double a[3][3]={{3,-1,4},{-1,2,-2},{2,-3,-2}}; double b[3]={7,-1,0};if(gauss(3,&a[0][0],b)!=0)for(i=0;i<=2;i++)printf("\nx[%d]=%f\n",i,b[i]);}int gauss(int n,double a[],double b[]){int *js,i,j,L,k,is,p,q;double d,t;js=malloc(n*sizeof(int));L=1;for(k=0;k<=n-2;k++){d=0.0;for(i=k;i<=n-1;i++)for(j=k;j<=n-1;j++){t=fabs(a[i*n+j]);if(t>d){d=t;is=i;js[k]=j;}}if(d+1.0==1.0)L=0;else{if(js[k]!=k)for(i=0;i<=n-1;i++){p=i*n+k;q=i*n+js[k];t=a[p];a[p]=a[q];a[q]=t;}if(is!=k){for(j=k;j<=n-1;j++){p=k*n+j;q=is*n+j;t=a[p];a[p]=a[q];a[q]=t;}t=b[k];b[k]=b[is];b[is]=t;}}if(L==0){free(js);printf("fail\n");return(0);}d=a[k*n+k];for(j=k+1;j<=n-1;j++){p=k*n+j;a[p]=a[p]/d;}b[k]=b[k]/d;for(i=k+1;i<=n-1;i++){for(j=k+1;j<=n-1;j++){p=i*n+j;a[p]=a[p]-a[i*n+k]*a[k*n+j];}b[i]=b[i]-a[i*n+k]*b[k];}}d=a[(n-1)*n+n-1];if(fabs(d)+1.0==1.0){free(js);printf("fail\n");return(0);}b[n-1]=b[n-1]/d;for(i=n-2;i>=0;i--){t=0.0;for(j=i+1;j<=n-1;j++)t=t+a[i*n+j]*b[j];b[i]=b[i]-t;}js[n-1]=n-1;for(k=n-1;k>=0;k--)if(js[k]!=k){t=b[k];b[k]=b[js[k]];b[js[k]]=t;} free(js);return(1);}结果:x1=2,x2=1,x3=0.5。

用C语言求解N阶线性矩阵方程Axb的简单解法

用C语言求解N阶线性矩阵方程Axb的简单解法

用C语言求‎解N阶线性‎矩阵方程A‎x=b的简单解‎法一、描述问题:题目:求解线性方‎程组Ax=b,写成函数。

其中,A为n×n的N阶矩‎阵,x为需要求‎解的n 元未‎知数组成的‎未知矩阵,b为n个常‎数组成的常‎数矩阵。

即运行程序时‎的具体实例‎为:转化为矩阵‎形式(为检验程序‎的可靠性,特意选取初‎对角线元素‎为0的矩阵‎方程组)即为:二、分析问题并‎找出解决问‎题的步骤:由高等代数‎知识可知,解高阶线性‎方程组有逆‎矩阵求解法‎、增广矩阵求‎解法等,而在计算机‎C 语言中,有高斯列主‎消元法、LU分解法‎、雅克比迭代‎法等解法。

为了与所学‎的高等代数‎知识相一致‎,选择使用“高斯简单迭‎代消元法”,与高等代数‎中的“增广矩阵求‎解法”相一致。

以下简述高‎斯消元法的‎原理:算法基本原‎理:首先,为了能够求‎解N阶线性‎方程组(N由用户输‎入),所以需要定‎义一个大于‎N维的数组‎a[dim+1][dim+1](dim为设‎定的最大维‎数,防止计算量‎溢出),当用户输入‎的阶数N超‎过设定值时‎提示重启程‎序重新输入‎。

进而,要判断方程‎组是否有解‎,无解提示重‎启程序重新‎输入,有解的话要‎判断是有无‎数不定解还‎是只有唯一‎一组解,在计算中,只有当原方‎程组有且只‎有一组解时‎算法才有意‎义,而运用高等‎代数的知识‎,只有当系数‎矩阵对应的‎行列式|A|≠0 时,原方程组才‎有唯一解,所以输入系‎数矩阵后要‎计算该系数‎矩阵的行列‎式 |A|(定义了ge‎t resu‎l t(n)函数计算),当行列式 |A|=0 时同样应提‎示重启程序‎重新输入,|A|≠0 时原方程组‎必然有且仅‎有唯一一组‎解。

判断出方程‎组有且仅有‎唯一一组解‎后,开始将系数‎矩阵和常数‎矩阵(合并即为增‎广矩阵)进行初等行‎变换(以a11 为基元开始‎,将第j列上‎j行以下的‎所有元素化‎为0),使系数矩阵‎转化为上三‎角矩阵。

初中数学教案:线性方程组的解法

初中数学教案:线性方程组的解法

初中数学教案:线性方程组的解法引言数学是一门让很多人感到困惑的学科,其中一个令学生普遍感到困惑的主题就是线性方程组的解法。

线性方程组是代数学中的一个基本概念,它在数学和其他领域中都有广泛的应用。

解线性方程组是我们在解决实际问题时经常遇到的任务之一。

本文将详细介绍初中数学课程中线性方程组的解法,帮助学生理解并掌握这一重要概念。

什么是线性方程组?在解决一些实际问题时,我们常常需要用到线性方程组。

线性方程组是由一组线性方程组成的集合,其中每个方程都具有相同的未知数。

一般来说,线性方程组的形式可以表示为:equationequation其中 equation 是未知数,而 equation 和 equation 是已知数。

解线性方程组的基本方法要解线性方程组,有几种基本的方法可供选择。

下面将介绍几种最常用的方法。

相消法是解线性方程组的一种简单且直观的方法。

它的基本思想是通过消除一个或多个未知数,从而简化方程组。

具体步骤如下:•检查方程组中是否有相等的方程,如果有,则只保留其中一个方程。

•比较两个或多个方程的某个系数的比例,通过乘以一个适当的系数使得两方程的该系数相等,从而达到消元的目的。

•通过代入法求解得到未知数的值。

相消法的优点是简单直观,能够快速解决一些简单的线性方程组。

然而,在处理复杂的方程组时,相消法可能不够高效。

2. 代入法代入法是解线性方程组的另一种常用方法。

它的基本思想是通过将一个方程的解代入到另一个方程中,从而得到新的方程组,进而求解未知数的值。

具体步骤如下:•选择一个方程,将该方程中的某个未知数用其他方程中的已知数表示。

•将其代入到其他方程中,得到一个新的方程组。

•通过求解新的方程组得到未知数的值。

代入法的优点是相对简单易懂,适用于一些特殊的线性方程组。

然而,当方程组较为复杂时,代入法需要进行多次代入计算,可能导致计算量较大。

矩阵法是解线性方程组的一种更为高级的方法。

它将线性方程组表示为矩阵的形式,通过矩阵的运算求解未知数的值。

C语言求解非线性方程、线性方程组代码

C语言求解非线性方程、线性方程组代码

本文档提供了牛顿法、列主元素消去法、LU分解法三类求解方程的代码,对应非线性方程及线性方程组。

利用C语言编写,采用txt文件输入、输出方式。

/*牛顿法求解非线性方程*/#include<stdio.h>#include<math.h>#include<stdlib.h>float f(float x) /* 定义函数f(x) */{ return 2*x*x+2*x+1-exp(2*x); }float f1(float x) /* 定义函数f(x)的导数f1(x) */{ return 4*x+2-2*exp(2*x); }main(){float x0,x1,eps; /*定义初值和迭代精度*/FILE *fp1,*fp2;if((fp1=fopen("in.txt","r"))==NULL){printf("Can't open this file!\n");exit(0);}fscanf(fp1,"%f %f",&x1,&eps);do{x0=x1;if(fabs(f(x0))<=eps) x1=x0;elsex1=x0-f(x0)/f1(x0); /*牛顿迭代*/}while(fabs(f(x1))>eps); /*循环条件*/fp2=fopen("out.txt","w");fprintf(fp2,"%e",x1);fclose(fp1);fclose(fp2);}/*列主元素消去法求解线性方程组*/#include<stdio.h>#include<math.h>#include<stdlib.h>#define N 3void main(){ int i,j,k,mi; /*定义变量类型*/ float max,temp;float a[N][N],b[N],x[N],r[N][N+1];FILE *fp1; /*输入系数矩阵及列向量b*/ if((fp1=fopen("in.txt","r"))==NULL){printf("Can't open this file!\n");exit(0);}for(i=0;i<N;i++)for(j=0;j<N+1;j++)fscanf(fp1,"%f",&r[i][j]);fclose(fp1);for(i=0;i<N;i++)for(j=0;j<N;j++)a[i][j]=r[i][j];for(i=0;i<N;i++)b[i]=r[i][N];for(j=0;j<N-1;j++) /*找出列主元素并交换*/{for(i=j+1,mi=j,max=fabs(a[j][j]);i<N;i++)if(fabs(a[i][j])>max){mi=i;max=fabs(a[i][j]);}if(j<mi){temp=b[j];b[j]=b[mi];b[mi]=temp;for(k=j;k<N;k++){temp=a[j][k];a[j][k]=a[mi][k];a[mi][k]=temp;}}for(i=j+1;i<N;i++){temp=-a[i][j]/a[j][j];b[i]+=b[j]*temp;for(k=j;k<N;k++)a[i][k]+=a[j][k]*temp;}}x[N-1]=b[N-1]/a[N-1][N-1]; /*消去求解*/ for(i=N-2;i>=0;i--){x[i]=b[i];for(j=i+1;j<N;j++)x[i]-=a[i][j]*x[j];x[i]/=a[i][i];}FILE *fp2;fp2=fopen("out.txt","w");for(i=0;i<N;i++)fprintf(fp2,"x[%d]=%f\n",i+1,x[i]);fclose(fp2);}/*线性方程组的LU分解法*/#include<stdio.h>#include<math.h>#include<stdlib.h>#define N 3void main(){ int i,j,k,n;float temp;float a[N][N],b[N],x[N],y[N],L[N][N],U[N][N],r[N][N+1];FILE *fp1;if((fp1=fopen("in.txt","r"))==NULL){printf("Can't open this file!\n");exit(0);}for(i=0;i<N;i++)for(j=0;j<N+1;j++)fscanf(fp1,"%f",&r[i][j]);fclose(fp1);for(i=0;i<N;i++)for(j=0;j<N;j++)a[i][j]=r[i][j];for(i=0;i<N;i++)b[i]=r[i][N];for(i=0;i<N;i++) /*矩阵分解*/{U[0][i]=a[0][i];L[i][i]=1.0;L[i][0]=a[i][0]/a[0][0];for(j=i+1;j<N;j++){ L[i][j]=0;U[j][i]=0;}}for(i=1;i<N;i++){for(j=i;j<N;j++){temp=0;for(k=0;k<i;k++)temp=temp+L[i][k]*U[k][j];U[i][j]=a[i][j]-temp;}for(j=i;j<N;j++){temp=0;for(k=0;k<i;k++)temp=temp+L[j][k]*U[k][i];L[j][i]=(a[j][i]-temp)/U[i][i];}}y[0]=b[0]; /*解该线性方程组*/ for(i=1;i<N;i++){temp=0;for(j=0;j<i;j++)temp=temp+L[i][j]*y[j];y[i]=b[i]-temp;}x[N-1]=y[N-1]/U[N-1][N-1];for(i=N-2;i>=0;i--){x[i]=y[i];for(j=i+1;j<N;j++)x[i]-=U[i][j]*x[j];x[i]/=U[i][i];}FILE *fp2;fp2=fopen("out.txt","w");for(i=0;i<N;i++)fprintf(fp2,"x[%d]=%f\n",i+1,x[i]);fclose(fp2);}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//解线性方程组#include<iostream.h>#include<iomanip.h>#include<stdlib.h>//----------------------------------------------全局变量定义区const int Number=15; //方程最大个数double a[Number][Number],b[Number],copy_a[Number][Number],copy_b[Number];//系数行列式int A_y[Number]; //a[][]中随着横坐标增加列坐标的排列顺序,如a[0][0],a[1][2],a[2][1]...则A_y[]={0,2,1...};int lenth,copy_lenth; //方程的个数double a_sum; //计算行列式的值char * x; //未知量a,b,c的载体//----------------------------------------------函数声明区void input(); //输入方程组void print_menu(); //打印主菜单int choose (); //输入选择void cramer(); //Cramer算法解方程组void gauss_row(); //Gauss列主元解方程组void guass_all(); //Gauss全主元解方程组void Doolittle(); //用Doolittle算法解方程组int Doolittle_check(double a[][Number],double b[Number]); //判断是否行列式>0,若是,调整为顺序主子式全>0void xiaoqu_u_l(); //将行列式Doolittle分解void calculate_u_l(); //计算Doolittle结果double & calculate_A(int n,int m); //计算行列式double quanpailie_A(); //根据列坐标的排列计算的值,如A_y[]={0,2,1},得sum=a[0][ A_y[0] ] * a[1][ A_y[1] ] * a[2][ A_y[2] ]=a[0][0]*a[1][2]*a[2][1];void exchange(int m,int i); //交换A_y[m],A_y[i]void exchange_lie(int j); //交换a[][j]和b[];void exchange_hang(int m,int n); //分别交换a[][]和b[]中的m和n 两行void gauss_row_xiaoqu(); //Gauss列主元消去法void gauss_all_xiaoqu(); //Gauss全主元消去法void gauss_calculate(); //根据Gauss消去法结果计算未知量的值void exchange_a_lie(int m,int n); //交换a[][]中的m和n列void exchange_x(int m,int n); //交换x[]中的x[m]和x[n]void recovery(); //恢复数据//主函数void main(){int flag=1;input(); //输入方程while(flag){print_menu(); //打印主菜单flag=choose(); //选择解答方式}}//函数定义区void print_menu(){system("cls");cout<<"------------方程系数和常数矩阵表示如下:\n";for(int j=0;j<lenth;j++)cout<<"系数"<<j+1<<" ";cout<<"\t常数";cout<<endl;for(int i=0;i<lenth;i++){for(j=0;j<lenth;j++)cout<<setw(8)<<setiosflags(ios::left)<<a[i][j];cout<<"\t"<<b[i]<<endl;}cout<<"-----------请选择方程解答的方案----------";cout<<"\n 1. 克拉默(Cramer)法则";cout<<"\n 2. Gauss列主元消去法";cout<<"\n 3. Gauss全主元消去法";cout<<"\n 4. Doolittle分解法";cout<<"\n 5. 退出";cout<<"\n 输入你的选择:";}void input(){ int i,j;cout<<"方程的个数:";cin>>lenth;if(lenth>Number){cout<<"It is too big.\n";return;}x=new char[lenth];for(i=0;i<lenth;i++)x[i]='a'+i;//输入方程矩阵//提示如何输入cout<<"====================================================\n";cout<<"请在每个方程里输入"<<lenth<<"系数和一个常数:\n";cout<<"例:\n方程:a";for(i=1;i<lenth;i++){cout<<"+"<<i+1<<x[i];}cout<<"=10\n";cout<<"应输入:";for(i=0;i<lenth;i++)cout<<i+1<<" ";cout<<"10\n";cout<<"==============================\n";//输入每个方程for(i=0;i<lenth;i++){cout<<"输入方程"<<i+1<<":";for(j=0;j<lenth;j++)cin>>a[i][j];cin>>b[i];}//备份数据for(i=0;i<lenth;i++)for(j=0;j<lenth;j++)copy_a[i][j]=a[i][j];for(i=0;i<lenth;i++)copy_b[i]=b[i];copy_lenth=lenth;}//输入选择int choose(){int choice;char ch;cin>>choice;switch(choice){case 1:cramer();break;case 2:gauss_row();break;case 3:guass_all();break;case 4:Doolittle();break;case 5:return 0;default:cout<<"输入错误,请重新输入:";choose();break;}cout<<"\n是否换种方法求解(Y/N):";cin>>ch;if(ch=='n'||ch=='N') return 0;recovery();cout<<"\n\n\n";return 1;}//用克拉默法则求解方程.void cramer(){int i,j;double sum,sum_x;char ch;//令第i行的列坐标为icout<<"用克拉默(Cramer)法则结果如下:\n";for(i=0;i<lenth;i++)A_y[i]=i;sum=calculate_A(lenth,0);if(sum!=0){cout<<"系数行列式不为零,方程有唯一的解:";for(i=0;i<lenth;i++){ ch='a'+i;a_sum=0;for(j=0;j<lenth;j++)A_y[j]=j;exchange_lie(i);sum_x=calculate_A(lenth,0);cout<<endl<<ch<<"="<<sum_x/sum;exchange_lie(i);}}else{cout<<"系数行列式等于零,方程没有唯一的解.";}cout<<"\n";}double & calculate_A(int n,int m) //计算行列式{ int i;if(n==1) {a_sum+= quanpailie_A();}else{for(i=0;i<n;i++){ exchange(m,m+i);calculate_A(n-1,m+1);exchange(m,m+i);}}return a_sum;}double quanpailie_A() //计算行列式中一种全排列的值{int i,j,l;double sum=0,p;for(i=0,l=0;i<lenth;i++)for(j=0;A_y[j]!=i&&j<lenth;j++)if(A_y[j]>i) l++;for(p=1,i=0;i<lenth;i++)p*=a[i][A_y[i]];sum+=p*((l%2==0)?(1):(-1));return sum;}//高斯列主元排列求解方程void gauss_row(){int i,j;gauss_row_xiaoqu(); //用高斯列主元消区法将系数矩阵变成一个上三角矩阵for(i=0;i<lenth;i++){for(j=0;j<lenth;j++)cout<<setw(10)<<setprecision(5)<<a[i][j];cout<<setw(10)<<b[i]<<endl;}if(a[lenth-1][lenth-1]!=0){cout<<"系数行列式不为零,方程有唯一的解:\n";gauss_calculate();for(i=0;i<lenth;i++) //输出结果{cout<<x[i]<<"="<<b[i]<<"\n";}}elsecout<<"系数行列式等于零,方程没有唯一的解.\n";}void gauss_row_xiaoqu() //高斯列主元消去法{int i,j,k,maxi;double lik;for(k=0;k<lenth-1;k++){j=k;for(maxi=i=k;i<lenth;i++)if(a[i][j]>a[maxi][j]) maxi=i;if(maxi!=k)exchange_hang(k,maxi);//for(i=k+1;i<lenth;i++){lik=a[i][k]/a[k][k];for(j=k;j<lenth;j++)a[i][j]=a[i][j]-a[k][j]*lik;b[i]=b[i]-b[k]*lik;}}}//高斯全主元排列求解方程void guass_all(){int i,j;gauss_all_xiaoqu();for(i=0;i<lenth;i++){for(j=0;j<lenth;j++)cout<<setw(10)<<setprecision(5)<<a[i][j];cout<<setw(10)<<b[i]<<endl;}if(a[lenth-1][lenth-1]!=0){cout<<"系数行列式不为零,方程有唯一的解:\n";gauss_calculate();for(i=0;i<lenth;i++) //输出结果{for(j=0;x[j]!='a'+i&&j<lenth;j++);cout<<x[j]<<"="<<b[j]<<endl;}}elsecout<<"系数行列式等于零,方程没有唯一的解.\n"; }void gauss_all_xiaoqu() //Gauss全主元消去法{int i,j,k,maxi,maxj;double lik;for(k=0;k<lenth-1;k++){for(maxi=maxj=i=k;i<lenth;i++){for(j=k;j<lenth;j++)if(a[i][j]>a[maxi][ maxj]){ maxi=i;maxj=j;}}if(maxi!=k)exchange_hang(k,maxi);if(maxj!=k){exchange_a_lie(maxj,k); //交换两列exchange_x(maxj,k);}for(i=k+1;i<lenth;i++){lik=a[i][k]/a[k][k];for(j=k;j<lenth;j++)a[i][j]=a[i][j]-a[k][j]*lik;b[i]=b[i]-b[k]*lik;}}}void gauss_calculate() //高斯消去法以后计算未知量的结果{int i,j;double sum_ax;b[lenth-1]=b[lenth-1]/a[lenth-1][lenth-1];for(i=lenth-2;i>=0;i--){for(j=i+1,sum_ax=0;j<lenth;j++)sum_ax+=a[i][j]*b[j];b[i]=(b[i]-sum_ax)/a[i][i];}}void Doolittle() //Doolittle消去法计算方程组{double temp_a[Number][Number],temp_b[Number];int i,j,flag;for(i=0;i<lenth;i++)for(j=0;j<lenth;j++)temp_a[i][j]=a[i][j];flag=Doolittle_check(temp_a,temp_b);if(flag==0) cout<<"\n行列式为零.无法用Doolittle求解.";xiaoqu_u_l();calculate_u_l();cout<<"用Doolittle方法求得结果如下:\n";for(i=0;i<lenth;i++) //输出结果{for(j=0;x[j]!='a'+i&&j<lenth;j++);cout<<x[j]<<"="<<b[j]<<endl;}}void calculate_u_l() //计算Doolittle结果{ int i,j;double sum_ax=0;for(i=0;i<lenth;i++){for(j=0,sum_ax=0;j<i;j++)sum_ax+=a[i][j]*b[j];b[i]=b[i]-sum_ax;}for(i=lenth-1;i>=0;i--){for(j=i+1,sum_ax=0;j<lenth;j++)sum_ax+=a[i][j]*b[j];b[i]=(b[i]-sum_ax)/a[i][i];}}void xiaoqu_u_l() //将行列式按Doolittle分解{ int i,j,n,k;double temp;for(i=1,j=0;i<lenth;i++)a[i][j]=a[i][j]/a[0][0];for(n=1;n<lenth;n++){ //求第n+1层的上三角矩阵部分即Ufor(j=n;j<lenth;j++){ for(k=0,temp=0;k<n;k++)temp+=a[n][k]*a[k][j];a[n][j]-=temp;}for(i=n+1;i<lenth;i++) //求第n+1层的下三角矩阵部分即L { for(k=0,temp=0;k<n;k++)temp+=a[i][k]*a[k][n];a[i][n]=(a[i][n]-temp)/a[n][n];}}}int Doolittle_check(double temp_a[][Number],double temp_b[Number]) //若行列式不为零,将系数矩阵调整为顺序主子式大于零{int i,j,k,maxi;double lik,temp;for(k=0;k<lenth-1;k++){j=k;for(maxi=i=k;i<lenth;i++)if(temp_a[i][j]>temp_a[maxi][j]) maxi=i;if(maxi!=k){ exchange_hang(k,maxi);for(j=0;j<lenth;j++){ temp=temp_a[k][j];temp_a[k][j]=temp_a[maxi][j];temp_a[maxi][j]=temp;}}for(i=k+1;i<lenth;i++){lik=temp_a[i][k]/temp_a[k][k];for(j=k;j<lenth;j++)temp_a[i][j]=temp_a[i][j]-temp_a[k][j]*lik;temp_b[i]=temp_b[i]-temp_b[k]*lik;}}if(temp_a[lenth-1][lenth-1]==0) return 0;return 1;}void exchange_hang(int m,int n) //交换a[][]中和b[]两行{int j; double temp;for(j=0;j<lenth;j++){ temp=a[m][j];a[m][j]=a[n][j];a[n][j]=temp;}temp=b[m];b[m]=b[n];b[n]=temp;}void exchange(int m,int i) //交换A_y[m],A_y[i]{ int temp;temp=A_y[m];A_y[m]=A_y[i];A_y[i]=temp;}void exchange_lie(int j) //交换未知量b[]和第i列{ double temp;int i;for(i=0;i<lenth;i++){ temp=a[i][j];a[i][j]=b[i];b[i]=temp;}}void exchange_a_lie(int m,int n) //交换a[]中的两列{ double temp;int i;for(i=0;i<lenth;i++){ temp=a[i][m];a[i][m]=a[i][n];a[i][n]=temp;}}void exchange_x(int m,int n) //交换未知量x[m]和x[n]{ char temp;temp=x[m];x[m]=x[n];x[n]=temp;}void recovery() //用其中一种方法求解后恢复数据以便用其他方法求解{for(int i=0;i<lenth;i++)for(int j=0;j<lenth;j++)a[i][j]=copy_a[i][j];for(i=0;i<lenth;i++)b[i]=copy_b[i];for(i=0;i<lenth;i++)x[i]='a'+i;a_sum=0;lenth=copy_lenth;}。

相关文档
最新文档