收藏 分销(赏)

基于Floyd算法的最短路径问题的求解c++1.doc

上传人:丰**** 文档编号:3926068 上传时间:2024-07-23 格式:DOC 页数:21 大小:100.04KB
下载 相关 举报
基于Floyd算法的最短路径问题的求解c++1.doc_第1页
第1页 / 共21页
基于Floyd算法的最短路径问题的求解c++1.doc_第2页
第2页 / 共21页
基于Floyd算法的最短路径问题的求解c++1.doc_第3页
第3页 / 共21页
基于Floyd算法的最短路径问题的求解c++1.doc_第4页
第4页 / 共21页
基于Floyd算法的最短路径问题的求解c++1.doc_第5页
第5页 / 共21页
点击查看更多>>
资源描述

1、沈阳理工大学课程设计专用纸 摘要现实生活中许多实际问题的解决依赖于最短路径的应用,其中比较常用的是floyd算法。通过floyd算法使最短路径问题变得简单化.采用图的邻接矩阵或邻接表实现最短路径问题中图的存储。采用Visual C+6。0的控制台工程和MFC工程分别实现基于floyd算法求最短路径的应用。关键词:最短路径;floyd算法;邻接矩阵;MFC工程目录1需求分析12算法基本原理12。1 邻接矩阵12.2 弗洛伊德算法23类设计23.1 类的概述23。2 类的接口设计33.3 类的实现44基于控制台的应用程序74.1 主函数设计74。2 运行结果及分析85基于MFC的应用程序95.1

2、图形界面设计95.1 程序代码设计115。3 运行结果及分析20结论21参考文献22II1 需求分析Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德命名。假若要在计算机上建立一个交通咨询系统则可以采用图的结构来表示实际的交通网络。这个资讯系统可以回答游客提出的各种问题。例如,一位旅客要从A城到B城,他希望选择一条途中中转次数最少的路线。假设图中每一站都需要换车,则这个问题反映到图上就是要找一条从顶点A到B所含边的数目最少的路径。我们只需从顶点A出发对图作广度优先搜索,一旦遇

3、到顶点B就终止。由此所得广度优先生成树上,从根顶点A到顶点B的路径就是中转次数最少的路径,路径上A与B之间的顶点就是途径中的中转站数。但是这只是一类最简单的图的最短路径的问题。有时对于旅客来说,可能更关心的是节省交通费用;对于司机来说里程和速度则是他们感兴趣的信息。为了在图上标示有关信息可对边赋以权的值,权的值表示两城市间的距离,或图中所需时间,或交通费用等等。此时路径长度的量度就不再是路径上边的数目,而是路径上边的权值之和.边赋以权值之后再结合最短路径算法来解决这些实际问题。Floyd算法是最短路径经典算法中形式较为简单,便于理解的一种。2 算法基本原理2。1 邻接矩阵邻接矩阵(Adjace

4、ncy Matrix):是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V=v1,v2,vn。G的邻接矩阵是一个具有下列性质的n阶方阵:(1)对无向图而言,邻接矩阵一定是对称的,而且对角线一定为零(在此仅讨论无向简单图),有向图则不一定如此。(2)在无向图中,任一顶点i的度为第i列所有元素的和,在有向图中顶点i的出度为第i行所有元素的和,而入度为第i列所有元素的和.(3)用邻接矩阵法表示图共需要个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n/2个空间。2.2 弗洛伊德算法弗洛伊德算法使用图的邻接矩阵arcsn

5、+1n+1来存储带权有向图.算法的基本思想是:设置一个n x n的矩阵A(k),其中除对角线的元素都等于0外,其它元素a(k)ij表示顶点i到顶点j的路径长度,K表示运算步骤。开始时,以任意两个顶点之间的有向边的权值作为路径长度,没有有向边时,路径长度为,当K=0时, A (0)ij=arcsij,以后逐步尝试在原路径中加入其它顶点作为中间顶点,如果增加中间顶点后,得到的路径比原来的路径长度减少了,则以此新路径代替原路径,修改矩阵元素。具体做法为:第一步,让所有边上加入中间顶点1,取Aij与Ai1+A1j中较小的值作Aij的值,完成后得到A(1);第二步,让所有边上加入中间顶点2,取Aij与A

6、i2+A2j中较小的值,完成后得到A(2),如此进行下去,当第n步完成后,得到A(n),A(n)即为我们所求结果,A(n)ij表示顶点i到顶点j的最短距离。因此弗洛伊德算法可以描述为:A(0)ij=arcsij; /arcs为图的邻接矩阵A(k)ij=minA(k1) ij,A(k-1) ik+A(k1) kj,其中 k=1,2,,n(1)定义一个n阶方阵序列:D(1),D(0),,D(n1).D(1) ij = G。arcsij;D(k) ij = min D(k-1)ij,D(k-1)ik + D(k1)kj ,k = 0,1,n1(2)其中D(0) ij是从顶点vi 到vj中间顶点是v0

7、的最短路径的长度;D(k) ij是从顶点vi 到vj中间顶点的序号不大于k的最短路径长度;D(n-1)ij是从顶点vi 到vj的最短路径长度。3 类设计3.1 类的概述类代表了某一批对象的共性和特征.类是对象的抽象.类这种数据类型中的数据既包含数据也包含操作数据的函数。声明类的一般形式:class 类名 private:私有的数据和成员函数;public:公用的数据和成员函数; ;定义对象:类名对象名;可以在类外定义成员函数,在函数名前加上类名,“::是作用域限定符或称作用域运算符用它说明函数式属于哪个类的。如下面程序中的voidMGraph:CreateMGraph(MGraph &G)函数

8、体3。2 类的接口设计#includeiostreaminclude string#include using namespace std;define MaxVertexNum 100#define INF 32767classMGraphprivate: char vertexMaxVertexNum; /顶点信息int edgesMaxVertexNumMaxVertexNum; /邻接矩阵intn,e;/顶点数和边数public: void CreateMGraph(MGraph ); /构造有向图voidPpath(int100,int,int); void Dispath(int1

9、00,int100,int); /输出最短路径void Floyd(MGraph G); /Floyd算法的具体实现;首先将所需文件名写好,定义类MGraph。在进行类体构造时将数据char vertexMaxVertexNum、int edgesMaxVertexNumMaxVertexNum和intn,e定义为私有数据,将成员函数void CreateMGraph(MGraph )、void Ppath(int100,int,int)、void Dispath(int100,int100,int)和void Floyd(MGraph G)定义为公用的,以便非类体内的数据调用函数。3。3 类

10、的实现void MGraph:CreateMGraph(MGraph &G)/构造有向图 inti,j,k,p; cout请输入顶点数和边数:; cinG。nG。e; coutG。vertexi; for (i=0;iG。n;i+) for (j=0;jG。n;j+) G.edgesij=INF; if (i=j) G.edgesij=0; for (k=0;kG。e;k+) cout”请输入第”k+1ijp; G。edgesij=p; void MGraph:Ppath(int pathMaxVertexNum,inti,int j) /Ppath()函数在path中递归输出从顶点vi到vj

11、的最短路径。 int k; k=pathij; if (k=1) / pathij=i时,顶点vi和vj之间无中间顶点,也就是说找到了始节点 return; Ppath(path,i,k); printf(”%d”,k); Ppath(path,k,j); void MGraph:Dispath(int AMaxVertexNum,int pathMaxVertexNum,int n)/输出最短路径的算法 inti,j; for (i=0;in;i+) for (j=0;jn;j+) if (Aij=INF) if (i!=j) printf(”从d到%d没有路径n”,i,j); else p

12、rintf( 从d到%d=路径长度:d路径:”,i,j,Aij); printf(%d,”,i); Ppath(path,i,j); printf(”dn”,j); voidMGraph::Floyd(MGraph G) int AMaxVertexNumMaxVertexNum,pathMaxVertexNumMaxVertexNum; inti,j,k; for (i=0;iAik+Akj) Aij=Aik+Akj; pathij=k;/ 表示从i节点到j节点,要经过k节点 Dispath(A,path,G。n); 4 基于控制台的应用程序4。1主函数设计int main()MGraph

13、G;G。CreateMGraph(G);G。Floyd(G);return 0;在程序的主函数部分,定义一个MGrapha类的对象G,调用成员函数CreateMGraph()和Floyd()分别完成了采用图的邻接矩阵实现最短路径问题中图的存储和采用Floyd算法求每一对顶点的最短路径的任务.4。2 运行结果及分析将待测图的相关数据输入则得到如图1的运行结果.图1 程序运行结果从图1可以看出:整个程序中的矩阵存储采用的是一维数组和动态内存分配方式.通过此类定义邻接矩阵,采用图的邻接矩阵实现最短路径问题中图的存储,然后通过主函数main调用class来实现,采用Floyd算法求每对顶点间最短路径从

14、某个源点到其余各顶点的最短路径。将图的基本信息输入,顶点数和边数4、8,顶点元素A、B、C、D,8条弧各自的序号和权值.运行程序得出每对顶点间的最短路径长度和路径。基于Floyd算法成功的解决了最短路径问题。5 基于MFC的应用程序MFC的图形界面程序与DOS界面程序的主要不同点是:MFC图形界面程序与DOS界面程序的输入输出方式不同,DOS界面程序采用字符交互式实现数据输入输出,主要通过cin,cout等I/O流实现,而MFC的图形程序界面采用标准Windows窗口和控件实现输入输出,因此必须在MFC类的框架下加入上面所设计的矩阵和方程组类,并通过图形界面的输入输出改造来完成。5。1图形界面

15、设计首先在VC中建立MFC AppWizard(exe)工程,名称为最短路径1203060213,并在向导的Step1中选择Dialog based,即建立基于对话框的应用程序,如下图23所示.图2建立MFC AppWizard(exe)工程图3 建立基于对话框的应用程序将对话框资源中的默认对话框利用工具箱改造成如下界面,如图4所示。图4表达式求值程序界面设计在图4的设计过程中,选择文件按钮用于进行文件的选择,选择文件后顶点个数也随之显示;起点和终点编辑框分别用于输入起点终点信息;提交按钮用于输出最终结果。5。1 程序代码设计为了能够将对话框界面上的控件能够与代码联系起来,需要为5个Edit

16、Box控件建立Member Variables,按Ctrl+w键进入MFC ClassWizard界面,选择Member Variables选项卡,可显示成员变量设置界面,如图5所示。图5成员变量设置界面通过该界面设置与5个Edit Box控件对应的成员变量,具体如表1所示。表1 控件基本信息控件ID成员变量类型成员变量名称IDC_EDIT_ENDintm_intEndIDC_EDIT_STARTintm_intStartIDC_EDIT_RESULTCstringm_intResulIDC_EDIT_INFOCstringm_strFileinfoIDC_EDIT_NUMIntm_nNum在

17、MFC中的主要代码:(1)。Ex_FloydDlg。cpp中的代码为:void CEx_exFloydDlg:OnButtonSel() /选择文件,并将文件中的数据保存到数组中/ TODO: Add your control notification handler code hereCFileDialog file(TRUE, NULL, NULL, NULL, _T((*.txt)。txt(*.doc)*.doc所有文件 (.*)|。* ),NULL); /*获得文件名*/CStringstrFileName;if(file.DoModal() = IDOK)m_strFileInfo

18、= file。GetFileName();if(m_strFileInfo。IsEmpty()MessageBox(你还没有选择任何文件!”);return;elseMessageBox(你选择文件:+ m_strFileInfo+请输入起点和终点);GetDlgItem(IDC_EDIT_START)EnableWindow(true);GetDlgItem(IDC_EDIT_END)EnableWindow(true);GetDlgItem(IDC_BUTTON_SUBMIT)EnableWindow(true);/将文件的数据读入到数组中CStdioFilefp;if(!fp。Open(

19、m_strFileInfo,CFile::modeRead)MessageBox(文件打开失败!”);return;int i=0;CStringstr;char temp;BOOL bread = fp。ReadString(str);temp = str。GetBuffer(0);n=atoi(temp);counts=nn;int tp; tp=new intcounts+1;m_nNUM=n;c=new intn+1;for(i=1; i=n; i+)ci= new int n+1;a=new int*n+1;for(i=1; i=n; i+)ai= new int n+1;r=new

20、 int*n+1;for(i=1; i=n; i+)ri= new int n+1;bread = fp.ReadString(str);i=0;while(bread)temp = str。GetBuffer(0);tpi+ = atoi(temp);bread = fp.ReadString(str);fp。Close();/将一维数组转化为二维数组放到数组c中for(i = 0; icounts; i+)if(tpi != 1)ci/n+1in+1 = tpi;elseci/n+1in+1 = maxint;UpdateData(FALSE);voidCEx_exFloydDlg::Ex

21、_floyd(intn,int c,int *a,int *r)inti,j,k;for(i=1; i=n; i+)for(j=1; j=n; j+)aij=cij;rij=0;for(i=1; i=n; i+)for(j=1; j=n; j+)for(k=1; k=n; k+)if(aik+akjaij)aij=aik+akj;rij=k;intCEx_exFloydDlg:Ex_output(int *r,inti,int j)int k;if(rij!=0)k=rij;Ex_output(r,i,k);strRes。Format(d-,k);m_strResult += strRes;E

22、x_output(r,k,j); return 0;void CEx_exFloydDlg:OnButtonSubmit() /执行floyd算法计算最优值和最优解/ TODO: Add your control notification handler code hereUpdateData(TRUE); /接受编辑框的数据CStringstrData; Ex_floyd(n,c,a,r); if(m_intStartnm_intStartnm_intEnd1)MessageBox(”您输入的终点有误,请重新输入”);strData.Format(”起点为:d”,m_intStart);m_

23、strResult += strData + ”rn ;strData。Format(终点为:d,m_intEnd);m_strResult += strData + ”rn”;strData。Format(”最优值:)shortestdd=dn”,m_intStart,m_intEnd,am_intStartm_intEnd);m_strResult += strData + ”rn”;strRes。Format(”最佳路径:%d,m_intStart);m_strResult += strRes;Ex_output(r,m_intStart,m_intEnd);strRes.Format(

24、d,m_intEnd);m_strResult += strRes;UpdateData(FALSE); /更新编辑框的数据(2)Ex_FloydDlg。h中的主要代码为:classCEx_exFloydDlg : public CDialog/ Constructionpublic:CEx_exFloydDlg(CWnd pParent = NULL);/ standard constructorvoidEx_floyd (intn,int *c,int a,int r);intEx_output(int r,inti,int j); / Dialog Data/AFX_DATA(CEx_e

25、xFloydDlg)enum IDD = IDD_EX_EXFLOYD_DIALOG ;CStringm_strFileInfo;intm_intEnd;intm_intStart;CStringm_strResult;intm_nNUM;protected:HICON m_hIcon;int n ; /图形中顶点的个数int *a; /最优值矩阵int c;/顶点之间的距离矩阵int *r;/路由矩阵int counts;int *tp;CStringstrRes; / Generated message map functions/AFX_MSG(CEx_exFloydDlg)virtua

26、l BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnButtonSel();afx_msg void OnButtonSubmit();(3)两个外部调用函数模块:voidCEx_exFloydDlg::Ex_floyd(intn,int c,int *a,int r)inti,j,k;for(i=1; i=n; i+)for(j=1; j=n; j+)aij

27、=cij;rij=0;for(i=1; i=n; i+)for(j=1; j=n; j+)for(k=1; k,k);m_strResult += strRes;Ex_output(r,k,j); return 0;if(file。DoModal() = IDOK)m_strFileInfo = file.GetFileName();if(m_strFileInfo。IsEmpty()MessageBox(你还没有选择任何文件!”);return;elseMessageBox(”你选择文件:”+ m_strFileInfo+”请输入起点和终点”);GetDlgItem(IDC_EDIT_STA

28、RT)EnableWindow(true);GetDlgItem(IDC_EDIT_END)EnableWindow(true);GetDlgItem(IDC_BUTTON_SUBMIT)EnableWindow(true);/将文件的数据读入到数组中CStdioFilefp;if(!fp。Open(m_strFileInfo,CFile:modeRead))MessageBox(文件打开失败!”);return;int i=0;CStringstr;char* temp;BOOL bread = fp。ReadString(str);temp = str。GetBuffer(0);n=ato

29、i(temp);counts=nn;int tp; tp=new intcounts+1;m_nNUM=n;c=new intn+1;for(i=1; i=n; i+)ci= new int n+1;a=new int*n+1;for(i=1; i=n; i+)ai= new int n+1;r=new intn+1;for(i=1; i=n; i+)ri= new int n+1;bread = fp。ReadString(str);i=0;while(bread)temp = str.GetBuffer(0);tpi+ = atoi(temp);bread = fp.ReadString(

30、str);fp.Close();/将一维数组转化为二维数组放到数组c中for(i = 0; icounts; i+)if(tpi != 1)ci/n+1i%n+1 = tpi;elseci/n+1i%n+1 = maxint;UpdateData(FALSE);5。3 运行结果及分析先选择“选择文件按钮”,在其中选择一个文件后如1.txt.会在顶点个数只读编辑框中显示出你所选文件中的顶点个数,分别在起点和终点编辑框中输入起点和终点,在点击提交,会出现如图5运行界面。图5单击提交按钮后的界面在图5中可以看出:进行操作时,单击选择文件框,选择所需要的文档,该文档存储了待测图的全部信息,随即生成顶点

31、个数.将你所要测的最短路径的一对顶点的起点和终点输入相应位置。待测信息输入完毕后,单击提交按钮,所测一对顶点的求出过程都会显示在结果对应的显示框中。成功的在MFC中实现了基于Floyd算法求每对顶点间的最短路径问题。MFC显示的界面,更清晰直观的反映出所要求解的最短路径问题,便于用户的理解和操作.结论本次课程设计主要研究基于Floyd算法的最短路径问题的求解。论文主体大致分为五个部分,第一部分介绍了Floyd算法的需求分析;第二部分介绍了算法的基本原理;第三部分主要是类设计,介绍了类、类的接口设计和类的实现;第四部分是基于控制台的应用程序;第五部分是基于MFC的应用程序。完整的叙述了所研究的问

32、题。编写程序过程中,首先需要了解邻接矩阵的概念,才能采用图的邻接矩阵实现最短路径问题中图的储存,然后才能采用Floyd算法求每一对顶点的最短路径。实验过程中用两种方式来实现基于Floyd算法的最短路径问题求解:一种是Win32 Console Application,输入输出采用传统DOS的字符式交互界面;另一种是MFC AppWizard(exe),输入输出采用基于Windows的图形式交互界面。编写DOS相关算法时采用类与对象进行编程,定义类MGraph,包含的数据元素有顶点信息、邻接矩阵和顶点数和边数,还包括成员函数void CreateMGraph(MGraph );用于构造有向图、v

33、oid Ppath(int100,int,int);、void Dispath(int100,int100,int);实现输出最短路径、void Floyd(MGraph G);则是Floyd算法的具体实现。通过定义对象对成员函数进行调用,完成基于floyd算法求最短路径问题.MFC虽然算法复杂,但是基于MFC的应用程序能更形象直接的供用户使用。最后要感谢老师和同学的帮助,我才能成功的完成这次课程设计的论文.这次课程设计作为学完面向对象程序设计课程后的一次全面的综合练习。通过这次设计增加我对面向对象程序设计的基础理论的理解,掌握面向对象程序设计开发的基本方法,进一步提高了综合运用所学知识的能力。参考文献1 谭浩强C+基础入门大全北京:清华大学出版社,2012:100-1022 郑莉,董渊,张瑞丰C+语言程序设计(第3版)北京:清华大学出版社,2007:25-603 钱能C+程序设计教程(第2版)北京:清华大学出版社,2007:1001304 欧阳志宏,董霖,钟俊华MFC程序设计轻松入门北京:人民邮电出版社,20095严蔚敏,吴伟民数据结构(C语言版)北京:清华大学出版社,2007:168-19219

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服