dijkstra与floyd方法求最短路径实验报告
- 格式:docx
- 大小:101.60 KB
- 文档页数:19
1.实验题目:单源最短路径的dijkstra解法两点间最短路径的动态规划解法Dijkstra算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。
主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。
注意该算法要求图中不存在负权边。
问题描述:在无向图G=(V,E) 中,假设每条边E[i] 的长度为w[i],找到由顶点V0 到其余各点的最短路径。
(单源最短路径)2.算法描述:1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径, 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。
在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v 到U中任何顶点的最短路径长度。
此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
2)算法步骤:a.初始时,S只包含源点,即S={v},v的距离为0。
U包含除v外的其他顶点,即:U={其余顶点},若v与U中顶点u有边,则<u,v>正常有权值,若u不是v的出边邻接点,则<u,v>权值为∞。
b.从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
c.以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
d.重复步骤b和c直到所有顶点都包含在S中。
单源最短路径的Dijkstra算法和多源最短路径的Floyd算法什么是单源最短路径?现在有6个结点,只求A到B、C、D、E、F的最短路径,⽽不同时求B到其他结点,C到其他结点,D到其他结点,E到其他结点,F到其他结点的最短路径。
即只求某⼀个结点到其他结点的最短路径。
Dijkstra算法是什么意思?现在试求A到B、C、D、E、F的最短路径。
先准备⼀个集合S,⾥⾯存放已经找到最短路径的结点,A到A⼀定是最短路径,故先把A放⼊集合S,即集合S:{A}从A出发找相邻的,到B、C的距离是20、38,选最⼩的,将B放⼊集合S,即集合S:{A,B}。
A→B的最短路径经过A、B从B出发找相邻的,到A、C、D的距离是9、15、37,到A的已经在集合S中了,忽略;到C⼀共是35,到D⼀共是57。
发现35⽐38⼩,集合S:{A,B,C}。
A→C的最短路径经过A、B、C从C出发找相邻的,到D、E的距离是18、5,到D⼀共的距离是53,到E⼀共的距离是40,53⼩于57,集合S:{A,B,C,D}。
A→D的最短路径经过A、B、C、D从D出发找相邻的,到A、F的距离是23、13,到A的忽略,到F⼀共的距离是66,没有到E的,那上⾯到E的就是最短路径,集合S:{A,B,C,D,E}。
A→E的最短路径经过A、B、C、E从E出发找相邻的,到D、F的距离是11、8,到D的忽略,到F⼀共的距离是48,48⼩于66,集合S:{A,B,C,D,E,F}。
A→F的最短路径经过A、B、C、E、F和Prim算法⼀样⼀样的!还是有区别的最⼩⽣成树所有结点都是相连的,单源最短路径不必所有结点都相连,只要源点与所有结点都相连就可以。
matlab最短路径实验报告一、实验目的本实验的目的是通过使用Matlab软件来实现最短路径算法,掌握最短路径算法的基本思路和实现方法,加深对图论知识的理解和应用能力。
二、实验原理最短路径算法是图论中一个重要的问题,它是指在一个加权有向图或无向图中从一个顶点到另一个顶点之间经过的边权值之和最小的路径。
常见的最短路径算法有Dijkstra算法、Bellman-Ford算法、Floyd-Warshall算法等。
本次实验采用Dijkstra算法来求解最短路径。
Dijkstra算法是一种贪心算法,它通过维护一个集合S来不断扩展已知最短路径集合S中所有节点到未知节点v之间的距离,并选取其中距离最小的节点u加入S中,直到所有节点都被加入S为止。
三、实验步骤1. 构建图首先需要构建一个加权有向图或无向图。
本次实验采用无向图,并使用邻接矩阵表示。
具体步骤如下:(1)定义节点数n和边数m;(2)定义邻接矩阵A(n*n),其中A(i,j)表示从i到j是否有边,如果有则为边的权值,如果没有则为无穷大。
2. 初始化(1)定义两个数组dist和visited,其中dist(i)表示从起点到节点i 的最短距离,visited(i)表示节点i是否已经加入集合S中;(2)将起点加入集合S中,并将visited数组对应位置设为1;(3)初始化dist数组,将所有非起点节点的距离设为无穷大。
3. 迭代更新(1)遍历集合S中所有节点u的邻居节点v,如果v未被加入集合S 中,则更新dist(v)的值。
具体而言,如果dist(u)+A(u,v)<dist(v),则更新dist(v)=dist(u)+A(u,v);(2)在所有未加入集合S中的节点中选取距离最小的节点u,并将其加入集合S中。
4. 输出结果输出起点到各个终点的最短路径长度和路径。
四、实验结果与分析本次实验构建了一个无向图,并使用Dijkstra算法求解了最短路径。
具体实现过程如下:1. 构建图构建了一个6个节点、8条边的无向图,邻接矩阵如下:0 6 4 Inf Inf Inf6 0 1 5 Inf Inf4 1 0 Inf Inf InfInf5InfInf0 Inf 1InfInfInf Inf0 2InfInfInf 1 2 0其中,Inf表示两个节点之间没有边。
Dijkstra最短路径算法实习报告1.引言交通诱导系统的一个核心技术是最优路径的选择技术。
根据交通网络模型中各顶点和顶点之间的长度、时间或费用等属性权值,通过Dijkstra最短路径算法,解决有向图即交通网络模型中源点到其他顶点的最短路径问题。
2.建立交通道路网络模型交通道路网是路径诱导的基础和对象,首先需要建立交通道路网络模型。
交通道路网中的路段具有属性,且同一路段的两个方向其属性一般不完全相同,有向图能够很好地表达实际的交通网络,便于处理同路段两个方向的不同属性和单行线、交叉口转向限制等特殊交通属性。
综上,采用带权有向图来表达交通道路网。
其中,道路的终点和十字路口通常定义为一个顶点,两个顶点之间的道路定义为一条弧,每条弧根据其距离、途中所需时间或交通费用等定义为路段权值。
在有向图上,一条以i为起点,以j为终点的路径是一些顶点的序列,其中前一条弧的终点是后一条弧的起点,一条路线用一个有序的点集描述,而一条路线的长度、时间或者费用等属性为这条路径上的所有弧的权值之和。
这样便建立好了交通道路网络的模型。
3.最短路径算法迪杰斯特拉(Dijkstra)算法是经典路径诱导规划算法,Dijkstra算法是一个按路径长度递增的次序产生最短路径的算法,算法比较简单,容易实现,但计算量较大。
3.1算法分析:首先引进辅助向量D,它的每个分量D[i]表示当前所找到的从始点v0到每个终点vi的最短路径的长度。
为D[i]赋初值,若从v0到vi有弧,则D[i]为弧上的权值,否则置D[i]为∞。
则长度为D[j]=Min{D[i]|vi∈v}的路径就是从v0出发的长度最短的一条最短路径,此路径为v0—vj。
设下一条长度次短的路径的终点是vk,则这条路径或者是v0—vk,或者是v0—vj—vk。
它的长度是v0到vk弧上的权值或D[j]和vj到vk弧上权值之和。
3.2算法正确性证明:设s为为已切得最短路径的终点的集合,则有结论:下一条最短路径(设其终点为vx)或者是v0—vx,或者是中间只经过s中的顶点而最后到达顶点x的路径。
数据结构实验报告五最短路径应用所学数据结构知识,独立完成问题分析^p ,结合数据结构理论知识,编写程序求解指定问题。
1.3 系统实现方案首先确定系统要实现怎样的目的,实现这些目的需要先实现哪些程序,这就是核心部分,划分出模块并写出其代码,此程序大致分了六大模块,由一个主函数组和五个自定义函数组成,而后是上机调试,将几大模块组成一个协调完整的能实现其功能的程序,最后提交设计报告二、系统分析^p :2.1设计思想用邻接矩阵来存储交通网络图的信息,运用迪杰斯特拉算法实现图上单最短路径问题,然后运用费洛伊德算法实现图中任意一对顶点间最短路径问题,这样就会实现旅客所要咨询的问题。
2.2设计要求该交通咨询系统要完成城市网络图的存储,并要实现求任意一个城市顶点到其他城市顶点的最短路径问题,还要实现任意两个城市顶点间的最短路径问题。
故设计要分成三部分,一是建立交通网络图的存储结构;二是解决单路径问题;最后再实现两个城市之间的最短路径问题。
设计要求:1.建立交通网络网的存储结构。
2.总体设计要画流程图。
3.提供程序测试方案。
4.界面友好。
2.3需求分析^p根据要求,需要在系统中建立无向图。
系统应该有高度灵活性,可以由用户根据当前交通网络图输入初始数据,并且可以更改。
系统根据用户的输入建立无向图的结构,并通过狄克斯特拉算法和弗洛伊德算法实现要求,并提供两种功能供用户选择。
2.4 算法描述录入城市及道路数据预置城市间的距离构建交通网交通查询系统根据无向图建立查询功能查询一个城市到其它城市的最短路径查询任意两城市间的最短路径狄克斯特拉算法的具体流程图开始初始化距离和路径 i=1 i++ j=1;j++;jn 修改最短路径和距离输出结果弗洛伊德算法的具体流程图开始初始化距离和路径设为从到的只以集合中的节点为中间节点的最短路径的长度最短路径不经过点k 最短路径经过点k 输出结果三、概要设计:程序中将涉及下列两个抽象数据类型:一个是图,一个是队列。
dijkstra 标号法floyd全文共四篇示例,供读者参考第一篇示例:Dijkstra算法和Floyd算法是两种最经典的图论算法,用来解决最短路径问题。
它们分别有着独特的算法思想和实现方式,在不同的场景中表现出各自的优势。
本文将介绍Dijkstra算法和Floyd算法的基本原理和应用,以及它们之间的区别和优缺点。
让我们来了解一下Dijkstra算法。
Dijkstra算法是由荷兰计算机科学家艾兹赫·迪克斯特拉于1956年提出的,用来解决单源最短路径问题。
所谓单源最短路径问题,就是给定一个带权有向图G=(V, E),其中V为顶点集合,E为边集合,每条边的权值为正数,以及一个源点s,求出从源点s到图中其他所有顶点的最短路径。
Dijkstra算法的基本思想是以源点为中心,逐步找出源点到其他各顶点的最短路径。
具体步骤如下:1. 创建一个集合S,用来存放已确定最短路径的顶点,初始时将源点加入其中;2. 初始化一个数组dist,用来记录从源点到各顶点的最短距离,初始时将源点到自身的距离设为0,其余顶点的距离设为无穷大;3. 重复以下步骤直到集合S包含所有顶点:a. 从dist中找出当前距禓源点最近的顶点u,将其加入集合S;b. 更新以u为起点的边的权值,更新dist数组中相应的距禓;4. 得到源点到其他各顶点的最短路径。
Dijkstra算法的时间复杂度为O(V^2),其中V为顶点数,这主要取决于选取最短路径顶点的方式。
当使用最小堆或斐波那契堆优化时,时间复杂度可以降至O(E+VlogV)。
1. 初始化一个二维数组dist,用来记录任意两顶点之间的最短路径距禓,初始时将dist[i][j]设为顶点i到顶点j的直接距禓,如果i和j 之间没有直接边,则设为无穷大;2. 重复以下步骤直到二维数组dist不再更新:a. 遍历所有顶点对(i, j),尝试以顶点k为中转点,更新dist[i][j]的值;3. 得到任意两顶点之间的最短路径。
目录交通咨询系统设计(最短路径问题)一、概述在交通网络日益发达的今天,针对人们关心的各种问题,利用计算机建立一个交通咨询系统。
在系统中采用图来构造各个城市之间的联系,图中顶点表示城市,边表示各个城市之间的交通关系,所带权值为两个城市间的耗费。
这个交通咨询系统可以回答旅客提出的各种问题,例如:如何选择一条路径使得从A城到B城途中中转次数最少;如何选择一条路径使得从A城到B城里程最短;如何选择一条路径使得从A城到B城花费最低等等的一系列问题。
二、系统分析设计一个交通咨询系统,能咨询从任何一个城市顶点到另一城市顶点之间的最短路径(里程)、最低花费或是最少时间等问题。
对于不同的咨询要求,可输入城市间的路程、所需时间或是所需费用等信息。
针对最短路径问题,在本系统中采用图的相关知识,以解决在实际情况中的最短路径问题,本系统中包括了建立图的存储结构、单源最短问题、对任意一对顶点间最短路径问题三个问题,这对以上几个问题采用了迪杰斯特拉算法和弗洛伊德算法。
并未本系统设置一人性化的系统提示菜单,方便使用者的使用。
三、概要设计可以将该系统大致分为三个部分:① 建立交通网络图的存储结构;② 解决单源最短路径问题;③ 实现两个城市顶点之间的最短路径问题。
四、详细设计建立图的存储结构定义交通图的存储结构。
邻接矩阵是表示图形中顶点之间相邻关系的矩阵。
设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下定义的n阶方阵。
注:一个图的邻接矩阵表示是唯一的!其表示需要用一个二维数组存储顶点之间相邻关系的邻接矩阵并且还需要用一个具有n个元素的一维数组来存储顶点信息(下标为i的元素存储顶点V的信息)。
i邻接矩阵的存储结构:附录#include<>#include<>#defineMVNum100#defineMaxint32767enumboolean{FALSE,TRUE}; typedefcharVertexType;typedefintAdjmatrix;typedefstruct{VertexTypevexs[MVNum];Adjmatrixarcs[MVNum][MVNum];}MGraph;intD1[MVNum],p1[MVNum];intD[MVNum][MVNum],p[MVNum][MVNum]; voidCreateMGraph(MGraph*G,intn,inte){inti,j,k,w;for(i=1;i<=n;i++)G->vexs[i]=(char)i;for(i=1;i<=n;i++)for(j=1;j<=n;j++)G->arcs[i][j]=Maxint;printf("输入%d条边的及w:\n",e);for(k=1;k<=e;k++){scanf("%d,%d,%d",&i,&j,&w);G->arcs[i][j]=w;}printf("有向图的存储结构建立完毕!\n"); }voidDijkstra(MGraph*G,intv1,intn){intD2[MVNum],p2[MVNum];intv,i,w,min;enumbooleanS[MVNum];for(v=1;v<=n;v++){S[v]=FALSE;D2[v]=G->arcs[v1][v];if(D2[v]<Maxint)p2[v]=v1;elsep2[v]=0;}D2[v1]=0;S[v1]=TRUE;for(i=2;i<n;i++){min=Maxint;for(w=1;w<=n;w++)if(!S[w]&&D2[w]<min){v=w;min=D2[w];}S[v]=TRUE;for(w=1;w<=n;w++)if(!S[w]&&(D2[v]+G->arcs[v][w]<D2[w])){D2[w]=D2[v]+G->arcs[v][w];p2[w]=v;}}printf("路径长度路径\n");for(i=1;i<=n;i++){printf("%5d",D2[i]);printf("%5d",i);v=p2[i];while(v!=0){printf("<-%d",v);v=p2[v];}printf("\n");}}voidFloyd(MGraph*G,intn){inti,j,k,v,w;for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(G->arcs[i][j]!=Maxint)p[i][j]=j;elsep[i][j]=0;D[i][j]=G->arcs[i][j];}for(k=1;k<=n;k++){for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(D[i][k]+D[k][j]<D[i][j]){D[i][j]=D[i][k]+D[k][j];p[i][j]=p[i][k];}}}}voidmain(){MGraph*G;intm,n,e,v,w,k;intxz=1;G=(MGraph*)malloc(sizeof(MGraph));printf("输入图中顶点个数和边数n,e:");scanf("%d,%d",&n,&e);CreateMGraph(G,n,e);while(xz!=0){printf("************求城市之间最短路径************\n");printf("=========================================\n");printf("1.求一个城市到所有城市的最短路径\n");printf("2.求任意的两个城市之间的最短路径\n");printf("=========================================\n");printf("请选择:1或2,选择0退出:\n");scanf("%d",&xz);if(xz==2){Floyd(G,n);printf("输入源点(或起点)和终点:v,w:");scanf("%d,%d",&v,&w);k=p[v][w];if(k==0)printf("顶点%d到%d无路径!\n",v,w);else{printf("从顶点%d到%d最短路径路径是:%d",v,w,v);while(k!=w){printf("--%d",k);k=p[k][w];}printf("--%d",w);printf("径路长度:%d\n",D[v][w]);}}elseif(xz==1)printf("求单源路径,输入源点v:");scanf("%d",&v);Dijkstra(G,v,n);}printf("结束求最短路径,再见!\n"); }。
利用Dijkstra算法计算最短路径摘要福格环游地球问题是一个十分典型的最短路径求解问题,题设给出了当时世界上主要交通网络图及交通通畅的城市之间来往所需时长,并限定了福格的出行方向(福格选择的是往东走),给出起止地点后要求找出福格环游世界天数最短的最佳路径。
我们认为,这个问题的实质在于最短路径的求解和优化。
我们对比图论中的多种最短路径算法,决定利用Dijkstra算法解决这个问题。
由于Dijkstra算法要求输入图G的关联矩阵,且图G为二维赋权图,而题中给出的地图可看成是三维环状地图,因此,我们对题设地图做相关处理,将其从起点处“切断”并展开为二维图,然后根据此图建立关联矩阵。
同时,我们考虑到最短路径可能会与切断线有交点,在切断线以西找出若干地点一分为二,修改关联矩阵。
对于题目中缺失的两处数据,本文将以当时的交通数据为基础,经过合理的数据处理,结合Google Earth测距软件与题目数据的合理类比,补充缺失数据,完成关联矩阵。
得到关联矩阵后,我们分别以伦敦、纽约和上海作为起点,调整关联矩阵起点和终点,用matlab编程进行求解得到最短环游时间和最短路径,进而判断出所选择的路径是否能让他赢得赌注。
根据我们的求解结果,在这三个城市,福格均能在80天内环游地球,赢得赌注。
本文进一步对此种算法的优缺点、灵敏度与推广性进行了分析,同时初步提出了两种优化方法。
关键词:最短路径算法 dijkstra算法算法优化一、问题重述儒勒•凡尔纳的著名小说《环游世界80天》中,英国绅士福格在伦敦与人打赌能够在80天内环游世界,这在当时的1872年是一个了不起的壮举。
当时最快的旅行方式是火车和轮船,然而世界上大部分地区还是靠马车、大象、驴子或者步行来旅行。
下面是一个从伦敦环游世界不同路线的交通网络图,福格选择的是往东走,每段路线所需要的天数显示在图上(见附录一),旅行的时间基于1872年能采用的旅行方式以及距离。
我们将解决以下问题:1.我们将设计一个算法为福格选择一条最佳路径,即环游世界天数最短,并判断所选择的路径是否能让他赢得赌注。
求最短路径经典算法详解-迪杰斯特拉(Dijkstra)、弗洛伊德(Floyd)什么是“迪杰斯特拉(Dijkstra)”算法? 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家于1959 年提出的,因此⼜叫。
是从⼀个顶点到其余各顶点的算法。
迪杰斯特拉算法主要特点是以起始点为中⼼向外层层扩展,直到扩展到终点为⽌。
⽤来解决什么样的问题? 解决的是有权图中最短路径问题,给定带权有向图G=(V, E)和源点v∈V,求从v到G中其余各顶点的最短路径应⽤案例:1.计算机⽹络传输的问题:怎样找到⼀种最经济的⽅式,从⼀台计算机向⽹上所有其它计算机发送⼀条消息。
2.交通运输问题,⾛那条路径最优解决思路步骤 基本思想:设置⼀个集合S存放已经找到最短路径的顶点,S的初始状态只包含源点v,对vi∈V-S,假设从源点v到vi的有向边为最短路径。
以后每求得⼀条最短路径v, …, vk,就将vk加⼊集合S中,并将路径v, …, vk , vi与原来的假设相⽐较,取路径长度较⼩者为最短路径。
重复上述过程,直到集合V中全部顶点加⼊到集合S中。
设计数据结构 : 1、图的存储结构:带权的邻接矩阵存储结构。
2、数组dist[n]:每个分量dist[i]表⽰当前所找到的从始点v到终点vi的最短路径的长度。
初态为:若从v到vi有弧,则dist[i]为弧上权值;否则置dist[i]为∞。
3、数组path[n]:path[i]是⼀个字符串,表⽰当前所找到的从始点v到终点vi的最短路径。
初态为:若从v到vi有弧,则path[i]为vvi;否则置path[i]空串。
4、数组s[n]:存放源点和已经⽣成的终点,其初态为只有⼀个源点v。
详细步骤及相关说明迪杰斯特拉算法(详细)Dist :存储了当前起点到其余各顶点的最短路径长度Path :存储了起点到其余各顶点的路径Set:标记了哪些顶点已经被选⼊了最短路径说明:+:表⽰起点到顶点没有直接相连-1:当前顶点在其最短路径上⾯没有前⼀个顶点或者没有关系初始状态0123456Dist0466+++Path-1000-1-1-1Set1000000从某个定点到其余各个顶点的最短路径选择距离起点最近的那个顶点,将其并⼊,然后扫描图中未被并⼊顶点的所有顶点。
实验报告 一、实验名称 求最短距离及最短路线。 二、实验目的 (1)掌握最短路径的基础知识,掌握求最短路径的方法。 (2)充分了解Dijkstra算法与Floyd算法的性质与原理。 (3)利用编程的方法求出一个无向图(有向图)中的最短路径。
三、实验内容与要求
求最短距离及最短路线。 1、用Dijkstra算法求从节点1到节点8的最短路,并用程序实现; 2、用Floyd算法求任意两点之间的最短路,并用程序实现; 3、程序实现所用语言不限;
四、实验原理与步骤 (一)Dijkstra算法
① ② ③ ④ ⑤ ⑥ ⑦ ⑧
4 5
2
6 1 7 8 3 9 3 2 6 11
11、实验原理: Dijstra为了算出图中某点到其它点的最短路径,提出了按路径的长度递增次序,逐步产生最短路径的算法,被称为Dijstra算法。Dijkstra算法采用的是一种贪心的策略,声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T,初始时,原点 s 的路径权重被赋为 0 (dis[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把dis[m]设为w(s, m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。初始时,集合T只有顶点s,然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,此时完成一个顶点, 然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。 然后,又从dis中找出最小值,重复上述动作,直到T中包含了图的所有顶点。
2、实验步骤: 此程序使用了visual studio2010进行编写,程序参考了《数据结构C++版》课本中的原有程序以及相关知识,并进行了一些改动。 (1) 建立一个class Dis类,用来记录起点到每个顶点的最短路径的信息。 (2) 建立一个Graph_DG类,存放图的顶点和边数、存储图的邻接矩阵以及程序中使用到的函数。 Graph_DG类中的主要函数: ① 析构函数:用于初始化顶点数和边数。 ② 构造函数:用于释放程序中开辟的内存空间。 ③ check_edge_value函数:判断输入边的数据是否是合法的。 ④ creatGraph函数:创造一个新的图表。 ⑤ print函数:打印出图的邻接矩阵。 ⑥ Dijkstra函数:Dijkstra算法的具体实现(利用实验原理中的算法进行程序设计)。 ⑦ Print_path函数:打印出最小路径以及最小路径的长度。 关于表的输入、打印等函数此处不再赘述。下面主要叙述Floyd函数的建立: ① 首先初始化dis数组并设置当前的路径; for (i = 0; i < this->vexnum; i++) { dis[i].path = "v" + to_string(static_cast(begin)) + "-->v" + to_string(static_cast(i + 1)); dis[i].value = arc[begin - 1][i]; } ② 设置起点到起点的路径为0; dis[begin - 1].value = 0; ③ 接下来利用count计算剩余顶点的最短路径,temp用于保存当前dis数组中最小的下标,min记录当前的最小值; ④ 把temp对应的顶点加入到已经找到的最短路径的集合中; ⑤ 为防止内存泄漏,此处我们选择加入条件arc[temp][i]!=INT_MAX的方法; ⑥ 不断更新最短路径和长度总和,直到算出最后结果; (3) 使用一个check函数判断输入的顶点个数和边的条数是否是合法的。 (4) 在主函数中建立表类的一个对象,要求用户输入图的顶点、边、边的权值等信息,并使用建立的对象调用上面所写的函数。
(二)Floyd算法 1、实验原理: 利用Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入两个矩阵,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。矩阵P中的元素b[i][j],表示顶点i到顶点j经过了b[i][j]记录的值所表示的顶点。假设图G中顶点个数为N,则需要对矩阵D和矩阵P进行N次更新。初始时,矩阵D中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞,矩阵P的值为顶点b[i][j]的j的值。 接下来开始,对矩阵D进行N次更新。第1次更新时,如果”a[i][j]的距离” > “a[i][0]+a[0][j]”(a[i][0]+a[0][j]表示”i与j之间经过第1个顶点的距离”),则更新a[i][j]为”a[i][0]+a[0][j]”,更新b[i][j]=b[i][0]。 同理,第k次更新时,如果”a[i][j]的距离”> “a[i][k-1]+a[k-1][j]”,则更新a[i][j]为”a[i][k-1]+a[k-1][j]”,b[i][j]=b[i][k-1]。更新N次之后,操作完成。
2、实验步骤: 本题与Dijkstra算法的程序大部分内容相似,仅有Floyd函数部分做了改动。同样的,此程序使用了visual studio2010进行编写,程序参考了《数据结构C++版》课本中的原有程序以及相关知识。 (1)建立一个Graph_DG类,定义图的顶点和边数、存储图的邻接矩阵以及程序中使用到的函数。 Graph_DG类中的主要函数: ① 析构函数:用于初始化顶点数和边数。 ② 构造函数:用于释放程序中开辟的内存空间。 ③ check_edge_value函数:判断输入边的数据是否是合法的。 ④ creatGraph函数:创造一个新的图表。 ⑤ Floyd函数:Floyd算法的具体实现(利用实验原理中的算法进行程序设计)。 ⑥ print函数:打印出图的邻接矩阵。 ⑦ Print_path函数:打印出最小路径以及最小路径的长度。 关于表的输入、打印等函数此处不再赘述。下面主要叙述Floyd函数的建立: ① 两个for循环的作用是把矩阵D初始化为邻接矩阵的值,矩阵p的初值则为各个边的终点顶点的下标。 for (i= 0; i< this->vexnum; i++) { for (j=0; j< this->vexnum; j++) { this->dis[i][j] = this->arc[i][j]; this->path[i][j] = j; } } ② 三重循环的作用是计算每个点对的最短路径,在三重循环中进行不断更新D和P矩阵的操作。 for (int m = 0;mvexnum;m++) { for (i = 0;i < this->vexnum; i++) { for (j = 0; j< this->vexnum; j++) { n=(dis[i][m]==INT_MAX||dis[m][j] == INT_MAX)?INT_MAX:(dis[i][m] + dis[m][j]); if (this->dis[i][j]>n) { this->dis[i][j]=n; this->path[i][j]=this->path[i][m]; } } } } ③ 为了防止溢出,我们多引入了一个n值。 n=(dis[i][m]==INT_MAX||dis[m][j] == INT_MAX)?INT_MAX:(dis[i][m] + dis[m][j]); (3)使用一个check函数判断输入的顶点个数和边的条数是否是合法的。 (4)在主函数中建立表类的一个对象,要求用户输入图的类型、顶点、边、边的权值等信息,并使用建立的对象调用上面所写的函数。
五、程序及其运行结果 (一)Dijkstra算法 程序: #include "StdAfx.h" #include #include using namespace std; class Dis { public: string path; int value; bool visit; Dis() { visit = false; value = 0; path = ""; } }; class Graph_DG { private: int vexnum; //图的顶点个数 int edge; //图的边数 int **arc; //邻接矩阵 Dis * dis; //记录各个顶点最短路径的信息 public: Graph_DG(int vexnum, int edge); ~Graph_DG(); bool check_edge_value(int start, int end, int weight); void createGraph(); void print(); void Dijkstra(int begin); void print_path(int); }; Graph_DG::Graph_DG(int vexnum, int edge) {//初始化顶点数和边数 this->vexnum = vexnum; this->edge = edge; arc = new int*[this->vexnum]; dis = new Dis[this->vexnum]; for (int i = 0; i < this->vexnum; i++) { arc[i] = new int[this->vexnum]; for (int k = 0; k < this->vexnum; k++) { arc[i][k] = INT_MAX; } } } Graph_DG::~Graph_DG() { delete[] dis; for (int i = 0; i < this->vexnum; i++) { delete this->arc[i];