下载此文档

n阶矩阵求逆矩阵(C++面向对象).pdf


文档分类:高等教育 | 页数:约22页 举报非法文档有奖
1/22
下载提示
  • 1.该资料是网友上传的,本站提供全文预览,预览什么样,下载就什么样。
  • 2.下载该文档所得收入归上传者、原创者。
  • 3.下载的文档,不会出现我们的网址水印。
1/22 下载此文档
文档列表 文档介绍
该【n阶矩阵求逆矩阵(C++面向对象) 】是由【mama】上传分享,文档一共【22】页,该文档可以免费在线阅读,需要了解更多关于【n阶矩阵求逆矩阵(C++面向对象) 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。:.
课程设计报告
word文档可自由复制编辑:.
信息系统开发语言(一)课程设计
——n阶方阵求逆的实现
一、课程设计目的
1、了解什么是矩阵及逆矩阵。
2、通过VC++。
3、巩固和加深学生对算法课程基本知识的理解和掌握。
4、培养利用算法知识解决实际问题的能力。
5、掌握利用程序设计语言进行算法程序的开发、调试、测试.
6、掌握书写算法设计说明文档的能力。
7、提高综合运用算法、程序设计语言、数据结构知识的能力。
二、问题描述
给出任意一个维数大于1小于256的矩阵,通过程序求出其逆矩阵。
aaa
000102

如Aaaa,存在矩阵B,使得矩阵A与B的乘积为单位矩阵,则称矩
101112
aaa

202122
阵B为矩阵A的逆矩阵。
三、问题分析
根据矩阵与逆矩阵的定义,即矩阵A与矩阵B相乘等于单位矩阵的思路,编辑程
序。
为使问题更加简单明了化,现举除一个具体例子,便于理解,我们在求解数学题
word文档可自由复制编辑:.
目中,经常会遇到这一类的题目:
如求方阵A的逆矩阵
aaa
000102

Aaaa
101112
aaa

202122
拿到这个题,我们首先应该是理解什么叫矩阵及逆矩阵,我们根据定义可知,一
个矩阵如果存在逆矩阵,那么这个矩阵的秩一定不会小于该矩阵的维数,拿到一个
题,要求一个逆矩阵的方法是很多的,比较常用的还是先把矩阵化为上三角或者下
三角矩阵,,判断矩阵是否存在逆矩阵,然后,然后根据矩阵与逆矩阵之积等于单
位矩阵从而得出逆矩阵,这是比较一般的思路,我们一下设计基本上也是以此为基
础的。
四、算法分析、设计与描述

对于矩阵求逆,逆矩阵的定义是:对于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列的各对应元之乘积的和。只要
按照该定义就可以求出两个矩阵的乘积。

-约旦法求解逆矩阵的算法描述如下:
word文档可自由复制编辑:.
首先,对于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!=k
4)m(i,j)=m(i,j)-m(i,k)*m(k,j),i,j=0,1,...,n-1;i,
j!=k
5)m(i,k)=-m(i,k)*m(k,k),i=0,1,...,n-1;i!=k
最后,根据在全选主元过程中所记录的行、列交换的信息进行恢复,恢复的原
则如下:在全选主元过程中,先交换的行(列)后进行恢复;原来的行(列)交换
用列(行)交换来恢复。(可插入流程图)
word文档可自由复制编辑:.
五、程序设计

该程序设计了一个类,用于存储用户数据的方阵阶数、用户输入的方阵数据以
及方阵的逆矩阵数据。因为用户需要计算的方阵的阶数不定,因此采用了double
型指针动态开辟内存的方式来存储用户输入的方阵数据和逆矩阵数据。同时,该类
定义了等方法,用来实现最成员变量的初始化,方阵求逆,矩阵相乘的操作。
word文档可自由复制编辑:.
程序运行开始,首先调用类的方法,在该方法中首先要求用户输入矩阵的阶
数,并根据该阶数开辟内存空间,接着要求用户输入方阵的数据,输入完毕后,程
序调用类的方法用以实现方阵的求逆,在求逆过程中,首先判断该矩阵是否存在逆
矩阵,若存在则进行求逆,若不存在则给出提示并要求用户重新输入。求逆完成后
存储结果并显示,同时程序调用类的方法对两个矩阵进行相乘操作,用来验证求逆
结果是否正确。
该程序设计的主要难点和重点在于方阵的逆矩阵求解方法,通过复****矩阵的相
关知识和查阅资料,决定采用高斯-约旦法来实现对方阵的求逆,为了计算的方
便,数据也是采用一维数据而不是二维数据才存储。
矩阵类matrix的uml图如下:

#include<iostream>
#include<iomanip>
usingnamespacestd;
double**B;//保存矩阵A与E的组合矩阵
intN=0;
word文档可自由复制编辑:.
voidInit()
//初始化B但是还没有输入A的值
{
cout<<"现在请该矩阵输入的维数N"<<endl;
do{
cin>>N;
if(N<1)cout<<"检查矩阵的维数是否正确!"<<endl;
}while(N<1);
B=newdouble*[N+1];//B[0][n]不用
inti;
for(i=0;i<=N;++i)
B[i]=newdouble[2*N+1];//B[n][0]不用
intj;
for(i=0;i<=N;++i)
for(j=0;j<=2*N;++j)
B[i][j]=(j-i==N)?1:0;
}
voidAinit()
//输入原矩阵每一行的每一个数的值
{
cout<<"请输入原矩阵每一行的每一个数的值:"<<endl;
inti,j;
for(i=1;i<=N;++i)
{
cout<<"输入第"<<i<<"行各数的的值:"<<endl;
for(j=1;j<=N;++j)
cin>>B[i][j];
word文档可自由复制编辑:.
}
cout<<"该矩阵为:"<<endl;
for(i=1;i<=N;++i)
{
for(j=1;j<=N;++j)
cout<<setw(9)<<setprecision(6)<<B[i][j];
cout<<endl;
}
}
intTo1(inti)
//在进行矩阵变成上三角是将第i行第i列的数变成1
//并且返回是否变换成功
//0---失败,也就是说改矩阵的秩不是N,并不能求出逆矩阵
//1---成功,返回后进行下一步程序
{
intj;
intii=i;
doubleij;
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)return0;//失败
word文档可自由复制编辑:.
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列的变为1
B[ii][i]/=ij;
return1;//成功返回
}
voidTo0(inti,intj)
//利用第i行第i列的数将第j行到第i行的第i列变为0
{
if(i==j)return;
intii=i,jj=j;
doubleij;
intn=(i<j)?-1:1;
//在下面是j+=n
//n用来检验是求上三角,还是下三角
//-1-------i<j也就是将下三角表为0
//1------i>j也就是将上三角变为0
for(;j!=i;j+=n)
for(ii=i,ij=B[j][i];ii<=2*N;++ii)
B[j][ii]-=ij*B[i][ii];
}
voidPrint()
{
inti,j;
intn=N*2;
word文档可自由复制编辑:.
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;
}
}
//intTo1(inti)
//在进行矩阵变成上三角是将第i行第i列的数变成1
//voidTo0(inti,intj)
//利用第i行第i列的数将第j行到第i行的第i列变为0
voidmain()
{
Init();//初始化B但是还没有输入A的值
Ainit();//输入原矩阵每一行的每一个数的值
inti;
intflag=1;
for(i=1;i<N;++i)
{
if(To1(i))
To0(i,N);
else
{
word文档可自由复制编辑:.
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;
}
六、程序运行、调试和结果分析
(包括异常处理)
在运行过程中是出现过很多问题的,错误也是非常之多的,就是各种不能运
行,先就针对错误比较突出的一些问题进行分析,错误一的提示:fatalerror
C1083:Cannotopenincludefile:'':Nosuchfileordirectory
,才发现原来在设置代码时我按照以前编
辑程序的经验预定义了一个头文件“”,当我把头文件“”省去
word文档可自由复制编辑:.
再次运行时,该错误就已经解决。
错误二的提示:warningC4508:'main':functionshouldreturnavalue;
'void'returntypeassumed
对于这个问题,是不应该犯的错误,这个错误的错误源在于编辑代码的最后一个
阶段,并没有注意到int定义的函数是有返回值的而void定义的函数才没有返
回值,于是我将int改成了void,此处错误就解决了。
具体错误代码如下:
intmain()
{
//定义一个矩阵类
matrixm;
//调用该类的set_data方法,来对其内部成员变量赋值
();
//对输入的矩阵求逆,如果求逆失败,说明输入的矩阵不存在逆矩阵,则要求用
户重//新输入
while(()==1)
();
//求逆成功后,计算两个矩阵的乘积是否为单位矩阵,用以验证求解的正确

();
}
错误三的提示:errorC2143:syntaxerror:missing';'before'}'
类似于错误三的错误是非常多的,这在编辑程序时是最容易出错,也是最容易
被遗忘的。在编辑程序时,我们必须要有严谨认真的态度,防止类似于错误二和错
误三的情况发生。
还有一个很奇怪的现象就是连接是显示的是0个错误,但是检测却出现了一个
word文档可自由复制编辑:.
错误,但是却可以运行,比如图一所示:
图一
word文档可自由复制编辑:.
图二
这个问题经过仔细研究后,发现在在图二中如果选择的是:“是”的话,则
运行不了,如果选择“否”就可以正常运行,并出现以上情况,出现以上情况的
原因是这个文件夹是我很早以前建立的,做这个实验的时候我并没有重新建立文
件夹,而是利用了以前做实验时,建好的文件,直接修改了文件里面的程序,直
接进行调试、检测以及运行,只要重新建立文件,就可以解决以上问题了,重新
建立文件夹后,运行情况如图三
word文档可自由复制编辑:.
图三
(多组数据测试)
运行中的第一种情况如图四:
word文档可自由复制编辑:.
图四
当输入的维数为0时,显示的文字为:逆矩阵为空,两矩阵相乘结果也为空,
这是如下程序的运行结果
matrix::matrix()
{
//将矩阵阶数初始化为0,并将两个指针指向NULL。
row=0;
in_buffer=NULL;
out_buffer=NULL;
}
matrix::~matrix()
{
//如果指针依然指向内存,则将指针指向的内存释放掉,并将指针指向
word文档可自由复制编辑:.
NULL
if(in_buffer)
{
delete[]in_buffer;
in_buffer=NULL;
}
if(out_buffer)
{
delete[]out_buffer;
out_buffer=NULL;
}
}
运行中的第二种情况:
此矩阵没有逆矩阵,是因为该矩阵的秩不等于该矩阵的维数2,设该矩阵用A表
示,也就是该矩阵的lAl=0,这是如下代码中的结果,在矩阵中,矩阵的秩小于
word文档可自由复制编辑:.
改矩阵的维数,该矩阵是没有逆矩阵的,这有矩阵逆矩阵的定义就知道了。
代码如下:
for(k=0;k<row;k++)
{
doublemax=0;
//全选主元
//寻找最大元素
for(i=k;i<row;i++)
{
for(j=k;j<row;j++)
{
//寻找最大值
if(fabs(*(out_buffer+i*row+j))>max)
{
max=*(out_buffer+i*row+j);
is[k]=i;
js[k]=j;
}
}
}
//如果最大值为0,则不存在逆矩阵,要求用户重新输入
if(0==max)
{
cout<<"该矩阵不存在逆矩阵,请重新输入"<<endl;
return1;
}
word文档可自由复制编辑:.
运行中的第三种情况:
由程序设定以及逆矩阵的性质可知,以上输入的矩阵是符合要求的,故输入后可
以得到逆矩阵,经过多次试验可知,只要维数大于1小于256,且符合矩阵逆矩阵
的定义,根据以上程序都是可以执行的。
七、总结与体会
我只能说C++这门课真的是太高深莫测了,你还能再复杂一点吗?可是更让我
觉得意外的是以前一直以为学C++知识为了开发软件应用软件什么的,没想到连我
最喜欢的数学都可以这样来解决啊!
我上课其实基本是还是蛮认真的,但是拿到题目却是愕然的呀!
原以为是很简单的东西没想到细究起来其实这么复杂,所有我深深的明白没有
浅显的知识,只有浅显的理解啊。
word文档可自由复制编辑:.
知识还是要一步一个脚印的扎稳啊,不能半知半解,要不然其实很不懂没什么
区别!经过这次试验我深深明白,上课听老师讲讲是远远不够的,一天24个小时,
我们有8个小时在睡觉,8个小时在上课,那么决定我们生命长度以及宽度的就是
那课余的8小时,所以,课后的时间我们应该好好利用,用心的学****达到不懂到
懂,懂到精的境界!不要小看任何事,任何简单的背后都会有不简单。
在学****C++以前,我认为C++只是在C语言的基础上的一种延伸,认为只要学
过C语言,就可以用C语言的那种设计思想来学****C++、设计C++程序。正是由于抱
了这种错误的思想,使我在一开始学****C++的时候遇到了很大的困难,我没有办法
体会面向对象的设计思想,我在学****这门课的时候老是想着实现这个函数功能的具
体过程,而没太注意对象分类的重要性。
随着课程学****的深入,我感觉到了利用类和对象、继承、封装等一系列知识可
以把我们程序中很多繁杂、重复的部分省略掉,还可以解决一些利用面向过程的设
计思想无法解决的问题,我自己也试着编写一些小的C++程序,当然在这个过程中
遇到了很多困难,其中调试带来的困难让我无法忘记,在调试程序的同时,我也总
结出来了一些调试的小技巧,让我在C语言课程设计中也受用匪浅。
在学****这门课的过程中,我感受到了自己亲自动手编程序、调程序的重要性,
我们要熟悉C++的语法、体会调试的思想,最好的一个手段就是自己动手编程、调
试,这会比我们一味的看书效果好得多。
另外,我还感觉到要编一个程序出来。严谨认真的态度是非常重要的,没有一
个严谨认真的态度,是做不成什么事情的,很多时候,我们出现的问题不是我们不
懂,而是我们的粗心大意导致了我们的错误连篇,出现错误的时候我们就必须检查
和纠正,这也是非常费时费力的,所以无论是在工作中还是在学****中,我们都必须
抱着认真严谨的态度来面对任何事,只有这样才可以事半功倍。同时我也认识到同
学之间的相互帮助以及同学之间的相互促进使非常重要的,在为这个论文设计奋战
了几天几夜之后,在查找程序几处提示错误的时候,自己怎么都找不到错误在哪
word文档可自由复制编辑:.
里,于是就向同学寻求帮助,他们一下子就找到了我的错误,我想这就是当局者迷
旁观者清吧,我们被自己的思想禁锢了,在生活也是如此,多听别人的意见、多与
别人交流,会更有益于我们的成长。
很高兴能够了解到C++的神奇魅力和面向对象程序设计的独特思想,它为我今
后的程序设计奠定了基础。
感谢老师对我们的悉心教授!
word文档可自由复制编辑:.
课程设计成绩评定表
等级
成绩优秀良好中等及格不及格
组成
。。。。。

。。。。。

。。。。。

。。。。。

。。。。


面。面。面。。



晰。晰。晰。。

晰。

很清晰。清晰。较清晰。欠清晰。不清晰。



很完整。完整。较完整。欠完整。不完整。



确。确。确。正确。确。

述。述。述。述。述。



晰、很完整。晰、完整。晰、较完整。晰、欠完整。晰、很完整。



入。入。入。入。入。
。。。。。

结结出创新成果。结出创新成果。
综合成绩评定:评阅老师(签章):
年月日
word文档可自由复制编辑

n阶矩阵求逆矩阵(C++面向对象) 来自淘豆网www.taodocs.com转载请标明出处.

非法内容举报中心
文档信息
  • 页数22
  • 收藏数0 收藏
  • 顶次数0
  • 上传人mama
  • 文件大小1.01 MB
  • 时间2023-03-26