高斯消元法解线性方程组C++实验报告2015年6月一、完成人王婧婷张子承郗滢二、问题描述线性方程组问题是大学阶段经常研究的问题,为了进一步熟悉理解高斯消元法的解题思路并且掌握编程语言在数学方面的应用。
且为解决线性方程组问题提供便利,要求给出线性方程组的矩阵,能够输出线性方程组的解。
三、解决方案设计基本程序流程为:(1)输入矩阵(2)运用初等行变换将其化为阶梯型矩阵(3)调用一个函数:r()求其秩(有解时)及其无解情况实验原理为:(1)系数矩阵及其增广矩阵经过初等行变换所得到的矩阵对应的方程与原方程同解(2)化为阶梯型矩阵过程(输入增广矩阵后,运用初等行变换,使其a[i][i]以下全为零,若a[i][i]为零,运用行变换交换使其不为零)(3)输出阶梯型矩阵(4)判断解情况并输出(解情况)(5)输出解四、模块及代码组织设计其基本模块分为三大部分,7小部分。
第一部分为输入矩阵阶段,用for语句实现。
第二部分是对矩阵进行一系列的处理以求得线性方程组的解,先运用初等行变换化为阶梯型,并输出化简矩阵;然后以线性方程组的秩判断其是否有解(规定无解时秩为零)。
第三部分是输出线性方程组的解情况及其解,如果无解即输出无解。
五、关键代码(1)实现化为阶梯型的代码实现此功能的代码是整个程序的重要内容,其需要进行的初等变换以实现校园的目的,使线性方程组得到简化。
其实现如下: for( i=0; i<=n-1&&i<m; i++ ){if(a[i][i]!=0){m1=a[i][i];for( j=i+1; j<=m-1; j++){m2=a[j][i];for( k=0; k<=n; k++ ){a[j][k]=a[j][k]-a[i][k]*m2/m1;}}}else if(a[i][i]==0){for( j=i+1; j<=m-1; j++){if(a[j][i]!=0){for(k=0; k<=n; k++)//交换i,j两行使a[i][i]!=0{b=a[i][k];a[i][k]=a[j][k];a[j][k]=b;}break;}}m1=a[i][i];for( j=i+1; j<=m-1; j++){m2=a[j][i];for( k=0; k<=n; k++ ){a[j][k]=a[j][k]-a[i][k]*m2/m1;}}}}(2)求出线性方程组系数矩阵秩的代码此代码是实现判断线性方程组解情况,其代码如下:int r(int m,int n,double c[][10000]){int i,j,k,b,e=0,f,x;double temp;double m1,m2;for(i=0; i<m; i++){b=0;for(j=0; j<n; j++){b=b+c[i][j];if (b!=0 ){e++;break;}}}for(i=0; i<m; i++){b=0;f=0;for(j=0; j<n; j++){b=b+c[i][j];if(b!=0 ) f=1;}if(f== 0 && c[i][n]!=0)//若系数全为0,非齐次项不为0; {return 0;x=1;break;}}if(x!=1)return e;}(3)分情况讨论解结构无解直接输出,单一解调用函数求解,无穷多解输出基础解析,代码如下:if(ra==0)cout<<"无解"<<endl;if(ra==n)//有唯一解{cout<<"唯一解"<<endl;danjie(n,a,x);for(i=0; i<n; i++)cout<<'x'<<(i)<<'='<<(x[i])<<endl;}else if(ra<n&&ra!=0){cout<<"无穷多解"<<endl;int ra=r(m,n,a);double b[ra][n-ra+1];double xx[ra][n-ra+1];for(i=0; i<ra; i++){for(k=0; k<n-ra+1; k++){b[i][k]=a[i][k+ra];}}for(i=0; i<ra; i++)a[i][ra]=b[i][n-ra];}danjie(ra,a,x);for(i=0; i<ra; i++){xx[i][0]=x[i];}for(j=1; j<=n-ra; j++){for(i=0; i<ra; i++){a[i][ra]=0;a[i][ra]=a[i][ra]-b[i][j-1];}danjie(ra,a,x);for(i=0; i<ra; i++){xx[i][j]=x[i];}}for(i=0; i<n; i++){if(i<ra){cout<<'x'<<(i+1)<<'=';for(j=0; j<=n-ra; j++){if(j==0){if(xx[i][j])cout<<xx[i][j];}else{if(xx[i][j]>0&&(xx[i][j-1]==0))cout<<xx[i][j]<<'k'<<(j);elseif(xx[i][j]>0&&xx[i][j-1]!=0)cout<<'+'<<xx[i][j]<<'k'<<(j);else if(xx[i][j]<0)cout<<xx[i][j]<<'k'<<(j); }}}else cout<<'x'<<(i+1)<<'='<<'k'<<(i+1-ra);cout<<endl;}cout << ra << endl;}void danjie(int n,double a[][10000],double x[]) {int i,j;for (i=n-1; i>=0; i--){if(i==n-1) x[i]=a[i][n]/a[i][i];elsefor(j=n-1; j>i; j--){a[i][n]=a[i][n]-x[j]*a[i][j];}x[i]=a[i][n]/a[i][i];}}运行实例(1) 2X1-X2+3X3+2X4=63X1-3X2+3X3+2X4=53X1-X2-X3+2X4=33X1-X2+X3-X4=4唯一解X1=1,X2=1,X3=1,X4=1(2)X1+X4=40X2+X5=20X3+X6=10X1+X2+X3=45X4+X5+X6=25无穷多解X1=15+X5+X6,X2=20-X5,X3=10-X6,X4=25+X5+X6,X5=X5,X6=.(3) X1+2X2=5X1+X2=42X1+X2=3无解。
六、错误、原因及解决办法七、收获及体会(1)识别对象,明确对象的功能,在解决问题过程中是基本的。
在此次研究的问题中,对象就是线性方程组以及高斯消元法,只有明确了高斯消元法的功能原理,以及线性方程组的基本性质,才能进行程序的基本设想与编写。
(2)对象的方法就是一个函数,与普通函数的抽象区别不大,同样是一个IPO,需要限定其功能,给一个能反映其功能的名称,确定它需要的数据、返回的数据。
对对象的方法而言,除了调用它的对象自身的属性数据外,完成功能需要的数据必须通过参数进行传递。
(3)更加深刻的理解了高斯消元法解线性方程组的思路与原理。
对编程软件的运用更加纯熟,在团队合作过程中大家集思广益,各抒己见,为程序的成功编写做出了贡献,也让大家理解了团队合作与互帮互助的重要性。
八、同类问题或拓展问题高斯消元法求矩阵的逆,伴随矩阵十、程序完整代码#include<iostream>#include<cstdio>using namespace std;void danjie(int n,double a[][10000],double x[]);int panding(int m,int n,double a[][10000]);int r(int m,int n,double c[][10000]);int main(){int i,j,k;int m,n;cout << "请输入方程组个数m和未知数个数n:" ;cin >>m>>n;double a[m][10000];double x[n];cout<<"请输入对应方程的增广矩阵:"<<endl;for(int i=0; i<=m-1; i++){for(j=0; j<=n; j++)cin>>a[i][j];}double m1,m2;int b=0;for( i=0; i<=n-1&&i<m; i++ ){if(a[i][i]!=0){m1=a[i][i];for( j=i+1; j<=m-1; j++){m2=a[j][i];for( k=0; k<=n; k++ ){a[j][k]=a[j][k]-a[i][k]*m2/m1;}}}else if(a[i][i]==0){for( j=i+1; j<=m-1; j++){if(a[j][i]!=0){for(k=0; k<=n; k++)//交换i,j两行使a[i][i]!=0{b=a[i][k];a[i][k]=a[j][k];a[j][k]=b;}break;}}m1=a[i][i];for( j=i+1; j<=m-1; j++){m2=a[j][i];for( k=0; k<=n; k++ ){a[j][k]=a[j][k]-a[i][k]*m2/m1;}}}} //此时已化为阶梯形矩阵,下面求秩,调用一个函数进行列交换,求秩int ra=r(m,n,a);for( i=0; i<=m-1; i++){for(j=0; j<=n; j++)cout <<a[i][j]<<' ';cout <<endl;}if(ra==0)cout<<"无解"<<endl;if(ra==n)//有唯一解{cout<<"唯一解"<<endl;danjie(n,a,x);for(i=0; i<n; i++)cout<<'x'<<(i)<<'='<<(x[i])<<endl; }else if(ra<n&&ra!=0){cout<<"无穷多解"<<endl;int ra=r(m,n,a);double b[ra][n-ra+1];double xx[ra][n-ra+1];for(i=0; i<ra; i++){for(k=0; k<n-ra+1; k++){b[i][k]=a[i][k+ra];}for(i=0; i<ra; i++){a[i][ra]=b[i][n-ra];}danjie(ra,a,x);for(i=0; i<ra; i++){xx[i][0]=x[i];}for(j=1; j<=n-ra; j++){for(i=0; i<ra; i++){a[i][ra]=0;a[i][ra]=a[i][ra]-b[i][j-1];}danjie(ra,a,x);for(i=0; i<ra; i++){xx[i][j]=x[i];}for(i=0; i<n; i++){if(i<ra){cout<<'x'<<(i+1)<<'=';for(j=0; j<=n-ra; j++){if(j==0){if(xx[i][j])cout<<xx[i][j];}else{if(xx[i][j]>0&&(xx[i][j-1]==0))cout<<xx[i][j]<<'k'<<(j);elseif(xx[i][j]>0&&xx[i][j-1]!=0)cout<<'+'<<xx[i][j]<<'k'<<(j);elseif(xx[i][j]<0)cout<<xx[i][j]<<'k'<<(j);}}}else cout<<'x'<<(i+1)<<'='<<'k'<<(i+1-ra);cout<<endl;}}cout << ra << endl;}void danjie(int n,double a[][10000],double x[]){int i,j;for (i=n-1; i>=0; i--){if(i==n-1) x[i]=a[i][n]/a[i][i];elsefor(j=n-1; j>i; j--){a[i][n]=a[i][n]-x[j]*a[i][j];}x[i]=a[i][n]/a[i][i];}}int r(int m,int n,double c[][10000]){int i,j,k,b,e=0,f,x;double temp;double m1,m2;/* for(i=0; i<m-1; i++){if(c[i][i]==0)//如果化为阶梯型矩阵后a[i][i]仍为0,交换列{for( j=i+1; j<=n-1; j++){if(c[i][j]!=0){for(k=i; k<=m-1; k++)//交换i,j两列使a[i][i]!=0{temp=c[k][j];c[k][j]=c[k][i];c[k][i]=temp;}break;}}for(j=i; j<=m-1; j++){m1=c[i][i];m2=c[j][i];for(k=i+1; k<=n; k++ ) c[j][k]=c[j][k]*m1-c[i][k]*m2;}}}*/for(i=0; i<m; i++){b=0;for(j=0; j<n; j++){b=b+c[i][j];if (b!=0 ){e++;break;}}}for(i=0; i<m; i++){b=0;f=0;for(j=0; j<n; j++){b=b+c[i][j];if(b!=0 ) f=1;}if(f== 0 && c[i][n]!=0)//若系数全为0,非齐次项不为0;{return 0;x=1;break;}}if(x!=1)return e; }。