n阶矩阵求逆矩阵(C++面向对象)
- 格式:doc
- 大小:395.00 KB
- 文档页数:22
课程设计报告信息系统开发语言(一)课程设计——n 阶方阵求逆的实现一、课程设计目的1、了解什么是矩阵及逆矩阵。
2、通过VC++6.0编写一个实现求矩阵逆矩阵的程序。
3、巩固和加深学生对算法课程基本知识的理解和掌握。
4、培养利用算法知识解决实际问题的能力。
5、掌握利用程序设计语言进行算法程序的开发、调试、测试.6、掌握书写算法设计说明文档的能力。
7、提高综合运用算法、程序设计语言、数据结构知识的能力。
二、问题描述给出任意一个维数大于1小于256的矩阵,通过程序求出其逆矩阵。
如⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡=222120121110020100a a a a a a a a a A ,存在矩阵B ,使得矩阵A 与B 的乘积为单位矩阵,则称矩阵B 为矩阵A 的逆矩阵。
三、问题分析根据矩阵与逆矩阵的定义,即矩阵A 与矩阵B 相乘等于单位矩阵的思路,编辑程序。
为使问题更加简单明了化,现举除一个具体例子,便于理解,我们在求解数学题目中,经常会遇到这一类的题目: 如求方阵A 的逆矩阵⎥⎥⎥⎦⎤⎢⎢⎢⎣⎡=222120121110020100a a a a a a a a a A拿到这个题,我们首先应该是理解什么叫矩阵及逆矩阵,我们根据定义可知,一个矩阵如果存在逆矩阵,那么这个矩阵的秩一定不会小于该矩阵的维数,拿到一个题,要求一个逆矩阵的方法是很多的,比较常用的还是先把矩阵化为上三角或者下三角矩阵,,判断矩阵是否存在逆矩阵,然后,然后根据矩阵与逆矩阵之积等于单位矩阵从而得出逆矩阵,这是比较一般的思路,我们一下设计基本上也是以此为基础的。
四、算法分析、设计与描述 1.算法分析和设计对于矩阵求逆,逆矩阵的定义是:对于n 阶方阵A ,若存在矩阵B ,使得AB=BA=E ,则称A 为可逆矩阵,简称A 可逆,并称B 为A 的逆矩阵。
A 存在逆矩阵的充要条件是|A|≠0。
若用定义的方法求解,计算量大,当矩阵的阶数很大时很浪费时间,为了节省时间,通过查阅资料和上网搜索,决定采用高斯-约旦发来进行方阵的求逆操作。
对于矩阵的乘法,利用矩阵乘法定义即可实现,矩阵的乘法的定义是:若A 是一个m*n 阶矩阵,B 是一个n*p 阶矩阵,则AB=C 是一个m*p 阶矩阵,而C 中的每一个(i,j )元都等于A 的第i 行中的各元和B 的第j 列的各对应元之乘积的和。
只要按照该定义就可以求出两个矩阵的乘积。
2.算法描述a.高斯-约旦法求解逆矩阵的算法描述如下:首先,对于 k 从 0 到 n - 1 作如下几步:1)从第 k 行、第 k 列开始的右下角子阵中选取绝对值最大的元素,并记住次元素所在的行号和列号,在通过行交换和列交换将它交换到主元素位置上。
这一步称为全选主元。
2)m(k, k) = 1 / m(k, k)3)m(k, j) = m(k, j) * m(k, k),j = 0, 1, ..., n-1;j != k4)m(i, j) = m(i, j) - m(i, k) * m(k, j),i, j = 0, 1, ..., n-1;i,j != k5)m(i, k) = -m(i, k) * m(k, k),i = 0, 1, ..., n-1;i != k 最后,根据在全选主元过程中所记录的行、列交换的信息进行恢复,恢复的原则如下:在全选主元过程中,先交换的行(列)后进行恢复;原来的行(列)交换用列(行)交换来恢复。
2.算法描述(可插入流程图)五、程序设计1.程序设计的基本思路该程序设计了一个类,用于存储用户数据的方阵阶数、用户输入的方阵数据以及方阵的逆矩阵数据。
因为用户需要计算的方阵的阶数不定,因此采用了double 型指针动态开辟内存的方式来存储用户输入的方阵数据和逆矩阵数据。
同时,该类定义了等方法,用来实现最成员变量的初始化,方阵求逆,矩阵相乘的操作。
程序运行开始,首先调用类的方法,在该方法中首先要求用户输入矩阵的阶数,并根据该阶数开辟内存空间,接着要求用户输入方阵的数据,输入完毕后,程序调用类的方法用以实现方阵的求逆,在求逆过程中,首先判断该矩阵是否存在逆矩阵,若存在则进行求逆,若不存在则给出提示并要求用户重新输入。
求逆完成后存储结果并显示,同时程序调用类的方法对两个矩阵进行相乘操作,用来验证求逆结果是否正确。
该程序设计的主要难点和重点在于方阵的逆矩阵求解方法,通过复习矩阵的相关知识和查阅资料,决定采用高斯-约旦法来实现对方阵的求逆,为了计算的方便,数据也是采用一维数据而不是二维数据才存储。
矩阵类matrix的uml图如下:2.程序代码及说明#include<iostream>#include<iomanip>using namespace std;double **B; //保存矩阵A 与 E的组合矩阵int N=0;void Init()//初始化B 但是还没有输入A的值{cout<<" 现在请该矩阵输入的维数 N"<<endl;do{cin>>N;if(N<1)cout<<" 检查矩阵的维数是否正确!"<<endl;}while(N<1);B=new double *[N+1]; //B[0][n]不用int i;for(i=0;i<=N;++i)B[i]=new double[2*N+1];//B[n][0]不用int j;for(i=0;i<=N;++i)for(j=0;j<=2*N;++j)B[i][j]=(j-i==N)?1:0;}void Ainit()//输入原矩阵每一行的每一个数的值{cout<<"请输入原矩阵每一行的每一个数的值:"<<endl;int i,j;for(i=1;i<=N;++i){cout<<"输入第 "<<i<<" 行各数的的值:"<<endl;for(j=1;j<=N;++j)cin>>B[i][j];}cout<<"该矩阵为:"<<endl;for(i=1;i<=N;++i){for(j=1;j<=N;++j)cout<<setw(9)<<setprecision(6)<<B[i][j];cout<<endl;}}int To1(int i)//在进行矩阵变成上三角是将第i行第i列的数变成1//并且返回是否变换成功//0---失败,也就是说改矩阵的秩不是N,并不能求出逆矩阵//1---成功,返回后进行下一步程序{int j;int ii=i;double ij;if(B[ii][ii]!=0) ij=B[ii][ii];else{for(j=i+1;j<=N;++j)if(B[j][i]!=0)break;if(j>N)return 0; //失败for(;i<=2*N;++i) //将第j行的加到第ii行B[ii][i]+=B[j][i];ij=B[ii][ii];}for(i=ii;i<=2*N;++i)//将第ii行第ii列的变为1B[ii][i]/=ij;return 1; //成功返回}void To0(int i,int j)//利用第i行第i列的数将第j行到第i行的第i列变为0{if(i==j)return;int ii=i,jj=j;double ij;int n=(i<j)?-1:1;//在下面是 j+=n//n用来检验是求上三角,还是下三角//-1-------i<j 也就是将下三角表为0//1------i>j 也就是将上三角变为0for(;j!=i;j+=n)for(ii=i,ij=B[j][i];ii<=2*N;++ii)B[j][ii]-=ij*B[i][ii];}void Print(){int i,j;int n=N*2;cout<<endl<<"该矩阵的逆矩阵为"<<endl;for(i=1;i<=N;i++){for(j=N+1;j<=n;++j)cout<<setw(9)<<setprecision(6)<<B[i][j];cout<<endl;}}//int To1(int i)//在进行矩阵变成上三角是将第i行第i列的数变成1//void To0(int i,int j)//利用第i行第i列的数将第j行到第i行的第i列变为0void main(){Init(); //初始化B 但是还没有输入A的值Ainit(); //输入原矩阵每一行的每一个数的值int i;int flag=1;for(i=1;i<N;++i){if(To1(i))To0(i,N);else{cout<<"改矩阵的秩小于 N ,没有逆矩阵"<<endl;flag=0;break;}}for(i=N;i>=1&&flag==1;--i){if(To1(i))To0(i,0);else{cout<<"改矩阵的秩小于 N ,没有逆矩阵"<<endl;flag=0;break;}}if(flag==1)Print();cin>>i;}六、程序运行、调试和结果分析1.程序运行中出现的问题及调试手段(包括异常处理)在运行过程中是出现过很多问题的,错误也是非常之多的,就是各种不能运行,先就针对错误比较突出的一些问题进行分析,错误一的提示: fatal error C1083: Cannot open include file: 'stdafx.h': No such file or directory 执行 cl.exe 时出错.根据英文提示,才发现原来在设置代码时我按照以前编辑程序的经验预定义了一个头文件“stdafx.h”,当我把头文件“stdafx.h”省去再次运行时,该错误就已经解决。
错误二的提示: warning C4508: 'main' : function should return a value; 'void' return type assumed对于这个问题,是不应该犯的错误,这个错误的错误源在于编辑代码的最后一个阶段,并没有注意到int定义的函数是有返回值的而void定义的函数才没有返回值,于是我将int改成了void,此处错误就解决了。