图最短路径实验报告
图的最短路径实验探究
朱阿杰/陈俊洪
2013年11月20日实验探究一
Dijkstrua最短路径算法的实验检测:
边的权值非负情况下为什么在有向无环图(DAG)能实现?(详细阐述见分析)
分析:
对于起点v(出度不为0),将从它指出的所有点存有队列,判断最小的权值(>=0)依次与v连接。
由于不存在环,最终必然生成一颗树,同时产生一条最小路径从v到达点w。
测试数据(tinyEWDAG.txt)
执行命令:% java DijkstraSP tinyEWDAG.txt 5 测试结果:
2.存在负权边的无环图
实验数据修改:
实验结果:
分析:
根据Dijkstra算法,同理可得对于无环的负权图,也将生产一颗树;同时包含v-->w的最短路径。
3.边的权值非负的普通(可以有环)有向图
测试数据:
执行指令:% java DijkstraSP tinyEWD.txt 0
测试结果:
分析:
从以上结果说明,在非负权的有向图中,不管是否存在环,都存在一至多条最短路径从v-->w。
4.边存在负权值的普通(可以有环)有向图
测试数据修改:
实验结果:
5存在负权重环的有向图实验数据:
实验结果:
分析:
由于在生产的有向图中,存在权重为负的环,根据Dijkstra算法的特性,将出现无限次遍历环的每一个节点... ...(权值的总和趋于-00).
实验探究二
“基于拓扑排序”的最短路径的实验测试:
1)有环有负权值
分析:
同样的测试数据,当利用AcyclicSP类测试时,由于该算法基于拓扑排序的最小路径生成过程当中应用深搜进行图的遍历,当存在环而且又有负权值时,亦有可能出现无限遍历,无法找出最小路径。
因此,AcyclicSP算法在有环且有负权重边的情况下可能失效。
3)权非负无环图(DAG)
分析:
测试结果同上。
AcyclicSP算法的有效性。
边v-->w只可能被放松一次,当且仅当distTo(w)变小时。
当所有数据非负时,通过AcyclicSP 遍历一定可以找出任意两点的一条最短路径。
附加实验(略):
l 有向无环图最长路径实验
l 有向有环图最长路径实验
实验总结:
对于一般的有向图,只要不存在负权值,用Dijkstra算法比较合适;而对于存在负权值的的有向图,只要不存在环,AcyclicSP算法都可以解决。
最短路径的实验报告
最短路径的实验报告最短路径的实验报告引言:最短路径问题是图论中一个经典的问题,涉及到在一个带有权重的图中找到两个顶点之间的最短路径。
本实验旨在通过实际操作和算法分析,深入探讨最短路径算法的性能和应用。
实验设计:本次实验使用了Dijkstra算法和Floyd-Warshall算法来解决最短路径问题。
首先,我们使用Python编程语言实现了这两个算法,并对它们进行了性能测试。
然后,我们选择了几个不同规模的图进行实验,以比较这两种算法的时间复杂度和空间复杂度。
最后,我们还在实际应用中使用了最短路径算法,以验证其实用性。
实验过程:1. 实现Dijkstra算法Dijkstra算法是一种贪心算法,用于求解单源最短路径问题。
我们首先实现了该算法,并对其进行了性能测试。
在测试中,我们使用了一个包含1000个顶点和5000条边的图,记录了算法的运行时间。
结果显示,Dijkstra算法的时间复杂度为O(V^2),其中V表示图中的顶点数。
2. 实现Floyd-Warshall算法Floyd-Warshall算法是一种动态规划算法,用于求解所有顶点对之间的最短路径。
我们在Python中实现了该算法,并对其进行了性能测试。
在测试中,我们使用了一个包含100个顶点和5000条边的图,记录了算法的运行时间。
结果显示,Floyd-Warshall算法的时间复杂度为O(V^3),其中V表示图中的顶点数。
3. 比较两种算法通过对Dijkstra算法和Floyd-Warshall算法的性能测试,我们可以看到,Dijkstra算法在处理较大规模的图时性能更好,而Floyd-Warshall算法在处理较小规模的图时性能更好。
因此,在实际应用中,我们可以根据图的规模选择合适的算法。
4. 应用实例为了验证最短路径算法的实际应用性,我们选择了一个城市交通网络图进行实验。
我们使用了Dijkstra算法来计算两个城市之间的最短路径,并将结果与实际的驾车时间进行比较。
实验四图的最短路径弗洛伊德算法实现
数据结构与算法课程实验报告实验四:图的相关算法应用姓名:王连平班级:09信科2班学号:I09630221实验四图的相关算法应用一、实验内容求有向网络中任意两点之间的最短路。
二、实验目的掌握图和网络的定义,掌握图的邻接矩阵、邻接表和十字链表等存储表示。
掌握图的深度和广度遍历算法,掌握求网络的最短路的标号法和floyd算法。
三、问题描述对于下面一张若干个城市以及城市间距离的地图,从地图中所有可能的路径中求出任意两个城市间的最短距离及路径,给出任意两个城市间的最短距离值及途径的各个城市。
四、问题的实现4.1数据结构的抽象数据类型定义和说明1)typedef struct ArcCell{//储存弧信息int Distance;ArcCell *info;//此项用来保存弧信息,,在本实验中没有相关信息要保存}ArcCell,AdjMatrix[ MAX_VERTEX_NUM][ MAX_VERTEX_NUM];typedef struct{//储存顶点信息string vexs[ MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs;//邻接矩阵int vexnum , arcnum;//图的当前顶点数和弧数}MGraph;顶点信息和弧信息都是用来建立一个有向网G2)d[v][w];//G中各对顶点的带权长度若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点4.2主要的实现思路首先通过一个函数(CreateDN)建立图的邻接矩阵储存方式,一次输入某条弧的起点,终点,和权值。
通过调用Locate函数来找到该弧在邻接矩阵中的相应位置。
其次运用弗洛伊德算法来求各定点的最短路劲,具体思路为:如果从v到w有弧,则存在一条长度为arcs[v][w]的路径,该路径不一定是最短路径。
考虑路径(v,u,w)是否存在,若存在,比较(v,w)和(v,u,w)的长度,取较短者为从v到w的中间点序号不大于0的最短路径。
Dijkstra最短路径算法实习报告
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的路径。
动态规划算法实现多段图的最短路径问题算法设计与分析实验报告
动态规划算法实现多段图的最短路径问题算法设计与分析实验报告算法设计与分析实验报告实验名称 动态规划算法实现多段图的最短路径问题 评分 实验日期 年 月 日 指导教师 姓名 专业班级 学号一.实验要求1. 理解最优子结构的问题。
有一类问题的活动过程可以分成若干个阶段,而且在任一阶段后的行为依赖于该阶段的状态,与该阶段之前的过程如何达到这种状态的方式无关。
这类问题的解决是多阶段的决策过程。
在50年代,贝尔曼(Richard Bellman )等人提出了解决这类问题的“最优化原理”,从而创建了最优化问题的一种新的算法设计方法-动态规划。
对于一个多阶段过程问题,是否可以分段实现最优决策,依赖于该问题是否有最优子结构性质,能否采用动态规划的方法,还要看该问题的子问题是否具有重叠性质。
最优子结构性质:原问题的最优解包含了其子问题的最优解。
子问题重叠性质:每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
问题的最优子结构性质和子问题重叠性质是采用动态规划算法的两个基本要素。
2.理解分段决策Bellman 方程。
每一点最优都是上一点最优加上这段长度。
即当前最优只与上一步有关。
U s 初始值,u j 第j 段的最优值。
⎪⎩⎪⎨⎧+==≠}.{min ,0ijiji js w u u u3.一般方法1)找出最优解的性质,并刻画其结构特征;2)递归地定义最优值(写出动态规划方程);3)以自底向上的方式计算出最优值;4)根据计算最优值时得到的信息,构造一个最优解。
步骤1-3是动态规划算法的基本步骤。
在只需要求出最优值的情形,步骤4可以省略,步骤3中记录的信息也较少;若需要求出问题的一个最优解,则必须执行步骤4,步骤3中记录的信息必须足够多以便构造最优解。
二.实验内容1.编程实现多段图的最短路径问题的动态规划算法。
2.图的数据结构采用邻接表。
3.要求用文件装入5个多段图数据,编写从文件到邻接表的函数。
4.验证算法的时间复杂性。
数据实验报告书 图的应用 最短路径问题
《数据结构》实验报告书实验内容:图的应用201100814***计科111 ***前言计算机编程中加工处理的对象是数据,而数据具有一定的组织结构,所以学习计算机编程仅仅了解计算机语言是不够的,还必须掌握数据的组织、存储和运算的一般方法,这便是数据结构课程中所研究的内容,也是我们编写计算机程序的重要基础,由于它对计算机学科起到承前启后的作用,因此本课程被列为计算机等相关专业最重要的专业基础课;同时数据结构是计算机专业教学的一门核心课程。
计算机各领域都要用到各种数据结构,而且要从事计算机科学与技术工作,尤其是计算机领域的软件开发工作,必须具备较强的数据结构基础。
数据结构课程内容丰富、学习量大,实践性强;隐含在各部分内容中的方法和技术多;算法设计具有动态性和抽象性等特点,看懂听明白与掌握会应用之间有相当大的一段距离。
所以学生必须多实践才能进一步加深对课程的理解,理解和掌握算法设计所需的方法和技术,为整个专业学习打下良好的基础。
一、实验目的1、使学生可以巩固所学的有关图的基本知识。
2、熟练掌握图的存储结构。
3、掌握如何应用图解决各种实际问题。
二、实验内容本次实验提供2个题目,学生可以任选一个!本人选了2个实验题目中的第2个题目如下:题目二:最短路径问题[问题描述]给定一个无向网,可以求得任意一对顶点之间的最短路径。
[基本要求]以邻接矩阵为存储结构,用迪杰斯特拉算法求解从某一源点到其它顶点之间的最短路径及最短路径长度。
[测试数据]由学生依据软件工程的测试技术自己确定。
三、算法设计1、程序所需头文件已经预处理宏定义如下#include<iostream.h>#include<iomanip.h>#define INFINITY 10000#define MAX_VERTEX_NUM 20typedef struct ArcCell{int adj;int *info;}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct Distance{int distance;}DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct {char data;}VertexType;typedef struct{VertexType vexs[MAX_VERTEX_NUM];//定义顶点类型AdjMatrix arcs;int vexnum,arcnum;}MGraph;int locatevex(MGraph G,char v){int i;for(i=0;i<G.vexnum;i++)if(G.vexs[i].data==v)return i;return -1;}2、生成图G的存储结构函数void Creatgraph(MGraph &G)//生成图G的存储结构{int i,j,k,weight;char v1,v2;cout<<"请输入图的顶点数和边数"<<endl;cin>>G.vexnum >>G.arcnum;cout<<"请输入各个顶点:";for(i=0;i<G.vexnum;i++){cin>>G.vexs[i].data;}for(i=0;i<G.vexnum;i++)for(j=0;j<G.vexnum;j++){if(j==i)G.arcs[i][j].adj=0;elseG.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=NULL;}cout<<"请输入两顶点以及它们之间的边的权值:"<<endl;for(k=0;k<G.arcnum;k++){cin>>v1>>v2>>weight;i=locatevex(G,v1);j=locatevex(G,v2);G.arcs[i][j].adj=weight;G.arcs[j][i].adj=G.arcs[i][j].adj;}}3、最短路径的处理函数void ShortestPath_FLOYD(MGraph G,DistancMatrix &D) //最短路径处理{int u,v,w;char P[MAX_VERTEX_NUM][MAX_VERTEX_NUM];for( v=0;v<G.vexnum;++v){for( w=0;w<G.vexnum;++w){D[v][w].distance=G.arcs[v][w].adj;if(D[v][w].distance<INFINITY )P[v][w]=G.vexs[v].data;else P[v][w]=-1;}int k=0;for( u=0;u<G.vexnum;++u){k++;for(v=0;v<G.vexnum;++v){for(w=0;w<G.vexnum;++w){if((D[v][u].distance+D[u][w].distance)<D[v][w].distance){D[v][w].distance=D[v][u].distance+D[u][w].distance;P[v][w]=G.vexs[u].data;}}}}int av, aw;cout<<"请输入要求的最短路径的两个顶点:";cin>>av>>aw;av++;aw++;cout<<"顶点"<<G.vexs[av].data<<"与顶点"<<G.vexs[aw].data<<"的最短路径长度为"<<D[av][aw].distance<<endl;cout<<"最佳路径为"<<'\t'<<G.vexs[av].data<<'\t';if(P[av][aw]!=G.vexs[av].data){cout<<P[av][aw]<<'\t';}cout<<G.vexs[aw].data<<endl;}}四、调试与测试我们开始测试数据:输入测试数据,如图:输入两点:结果如上图所示。
图-铁路最短路径实习报告
图-铁路最短路径实习报告09040502班学号:052415 朱博凯一、需求分析(1)本程序需要用户自行创建或打开已有的铁路图,城市名可以是中文也可以用英文表示,输入要求最短路径的两个城市,按回车键进行选定的操作!(2)程序功能:寻找两个指定城市之间的最短路径。
(3)测试地图:city.txt;二、概要设计为实现本程序功能,应以图结构存储城市、路径以及相应的信息。
1、图的抽象数据类型定义ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。
数据关系R:R={VR}VR={|v,w(-V且P(v,w),表示从v到w的弧,谓词P(v,w)定义了弧的意义或信息}基本操作P:CreateGraph(&G,V,VR);初始条件:V是图的顶点集,VR是图中弧的集合。
操作结果:按V和VR的定义构造图GDesoyGraph(&G);初始条件:图G存在操作结果:销毁图GLocateVex(G,u);初始条件:图G存在,u一G中顶点有相同特征操作结果:若G中存在顶点u, 则返回该顶点在图中位置;否则返回其它信息。
GetVex(G,v);初始条件:图G存在,v是G中某个顶点操作结果:返回v的值。
PutVex(&G,v,value);初始条件:图G存在,v是G中某个顶点操作结果:对v赋值valueFirstAdjVex(G,v);初始条件:图G存在,v是G中某个顶点操作结果:返回v的第一个邻接顶点。
若顶点在G中没有邻接顶点,则返回“空”NextAdjVex(G,v,w);初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点。
操作结果:返回v的(相对于w的)下一个邻接顶点。
若w是v的最后一个邻接点,则返回“空”InsertVex(&G,v);初始条件:图G存在,v和图中顶点有相同特征操作结果:在图G中增添新顶点vDeleteVex(&G,v);初始条件:图G存在,v是G中某个顶点操作结果:删除G中顶点v及其相关的弧InsertAcr(&G,v,w);初始条件:图G存在,v和w是G中两个顶点操作结果:在G中增添弧,若G是无向的,则还增添对称弧DeleteArc(&G,v,w);初始条件:图G存在,v和w是G中两个顶点操作结果:在G中删除弧,若G是无向的,则还删除对称弧DFSTraverser(G,v,Visit());初始条件:图G存在,v是G中某个顶点,Visit是顶点的应用函数操作结果:从顶点v起深度优先遍历图G,并对每个顶点调用函数Visit一次。
实验报告6-最短路径问题
HUNAN UNIVERSITY 课程实习报告题目最短路径问题学生姓名学生学号专业年级指导老师完成日期一、需求分析本实验是求最短路径的问题,从文件中读入有向网中顶点的数量和顶点间的票价的矩阵,以用户指定的起点,在文件中输出到其余各顶点的最短路径及花费。
(1)输入:输入的形式:(文件)5-1 10 3 20 -1-1 -1 -1 5 -1-1 2 -1 -1 15-1 -1 -1 -1 11-1 -1 -1 -1 -1(用户)输入起点:0输入值的范围:文件输入中,顶点数和矩阵中顶点间的票价均为整型int,用户输入中,起点数为整型int。
(2)输出的形式:(文件)源点0到顶点1的最小花费为:5路径为:0——>2——>1源点0到顶点2的最小花费为:3路径为:0——>2源点0到顶点3的最小花费为:10路径为:0——>2——>1——>3源点0到顶点4的最小花费为:18路径为:0——>2——>4(3)程序所达到的功能:在文件中给出有向网的顶点个数和顶点间的票价的矩阵,以用户指定的起点,在文件中输出起点到其余各顶点的最短路径及花费。
(4)测试数据:a.输入:(文件)5-1 10 3 20 -1-1 -1 -1 5 -1-1 2 -1 -1 15-1 -1 -1 -1 11-1 -1 -1 -1 -1(用户)输入起点:0输出:(文件)源点0到顶点1的最小花费为:5路径为:0——>2——>1源点0到顶点2的最小花费为:3路径为:0——>2源点0到顶点3的最小花费为:10路径为:0——>2——>1——>3源点0到顶点4的最小花费为:18路径为:0——>2——>4b.输入:(文件)5-1 10 3 20 -1-1 -1 -1 5 -1-1 2 -1 -1 15-1 -1 -1 -1 11-1 -1 -1 -1 -1(用户)输入起点:2输出:(文件)源点2到顶点0:没有连通路径源点2到顶点1的最小花费为:2路径为:2——>1源点2到顶点3的最小花费为:7路径为:2——>1——>3源点2到顶点4的最小花费为:15路径为:2——>4c.输入:(文件)618 10 3 20 -1 915 -1 -1 5 -1 -1-1 20 16 -1 -1 15-1 -1 30 -1 6 32 9 -1 20 -1 -1-1 8 12 -1 -1 5(用户)输入起点:5输出:(文件)源点5到顶点0的最小花费为:21路径为:5——>1——>3——>4——>0源点5到顶点1的最小花费为:8路径为:5——>1源点5到顶点2的最小花费为:12路径为:5——>2源点5到顶点3的最小花费为:13路径为:5——>1——>3源点5到顶点4的最小花费为:19路径为:5——>1——>3——>4d.输入:(文件)618 10 3 20 -1 915 -1 -1 5 -1 -1-1 20 16 -1 -1 15-1 -1 30 -1 6 32 9 -1 20 -1 -1-1 8 12 -1 -1 5(用户)输入起点:3输出:(文件)源点3到顶点0的最小花费为:8路径为:3——>4——>0源点3到顶点1的最小花费为:11路径为:3——>5——>1源点3到顶点2的最小花费为:11路径为:3——>4——>0——>2源点3到顶点4的最小花费为:6路径为:3——>4源点3到顶点5的最小花费为:3路径为:3——>5e.输入:(文件)3-1 -1 -1-1 -1 -1-1 -1 -1(用户)输入起点:1输出:(文件)源点1到顶点0:没有连通路径源点1到顶点2:没有连通路径f.输入:(文件)3-1 -1 -1-1 -1 -1-1 -1 -1(用户)输入起点:3输出:(文件)源点3到顶点0的最小花费为:-572562307路径为:3——>1——>0源点3到顶点1的最小花费为:-572662307路径为:3——>1源点3到顶点2的最小花费为:-572662307路径为:3——>2二、概要设计(1)所有抽象数据类型的定义:const int MaxNum=100000;//利用邻接矩阵存储图:class Graph{private:int *Adj;//保存邻接矩阵的一维数组j和k之间权值存储在Adj[j*Num+k]中int Num;public:Graph();~Graph();void Floyd(int start);};(2)算法的基本思想:采用邻接矩阵为图的存储结构,保存邻接矩阵的一维数组j和k之间权值存储Adj[j*Num+k]中,以用户指定的起点,进行弗洛伊德算法,先初始化最短路径,对角线元素设置为0,其他元素设置为边的权值,没有有向边设置为MaxNum,依次插入中间点k,判断是否检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,若不成立则路径不改变,若成立则更新最短路径,设置Dis(i,j) = Dis(i,k) + Dis(k,j),直至循环结束,更新后的最短路径入栈,在文件中输出到其余各顶点的最短路径及花费。
数据结构实验报告 最短路径
实验报告实验名称最短路径课程名称数据结构与算法实验||专业班级:信息安全学号:姓名:实验六最短路径一、实验目的1.学习掌握图的存储结构2.学会编写求最短路径的算法二、实验内容1、实验题目编写代码实现Dijkstra生成最短路径的算法,其中要有完整的图的输入输出2、简单介绍图的存储:用邻接矩阵,这样会方便不少。
邻接矩阵是一个二维数组,数组中的元素是边的权(一些数值),数组下标号为结点的标号。
(1)例如二维数组中的一个元素M[5][6]的值为39,则表示结点5、6连接,且其上的权值为39。
(2)用邻接矩阵存储图,对图的读写就简单了。
因为邻接矩阵就是一个二维数组,因此对图的读写就是对二维数组的操作。
只要能弄清楚边的编号,就能把图读入了。
用一对结点表示边(也就是输入的时候输入一对结点的编号)求最短路径的算法:求最短路径就是求图中的每一个点到图中某一个给定点(这里认为是编号为0的点)的最短距离。
具体算法就是初始有一个旧图,一个新图。
开始的时候旧图中有所有的结点,新图中初始为只有一个结点(源点,路径的源头)。
整个算法就是不停的从旧图中往新图中添加点,直到所有的点都添加到新图中为止。
要实现这个算法,除了用二维数组保存图,还需要使用到两个辅助的数组数组find[N]:此数组是用来表示标号对应的结点是否已经被添加到新图中(因为只有旧图中的点我们才需要添加到新图中,并且只有旧图中点到源点的距离,我们才需要进行更新)其中N为图中结点的个数。
数组distance[N]:此数组记录图中的点到源点的距离。
这个数组里面存放的值是不断进行更新的。
其中N为图中结点的个数。
3、程序简单模板只是参考,不需要照着这个来写//最短路径#ifndef MYGRAPH_H_#define MYGRAPH_H_class MyGraph{public:void readDirectedGraph();MyGraph(int size);//构造函数中设置图的大小,分配空间void writeGraph();void shortPath(int source);//求最短路径protected:private:int **m_graph;//用二维数组保存图int m_size;//图的大小};#endif///////////////////////////////////////////// //////////////////////////构造函数中设置图的大小,分配空间MyGraph::MyGraph(int size){int i,j;m_size=size;//给图分配空间m_graph=new int* [m_size];for (i=0;i<m_size;i++){m_graph[i]=new int[m_size];}for (i=0;i<m_size;i++){for(j=0;j<m_size;j++){m_graph[i][j]=INT_MAX;}}}三、实验代码#include<iostream>#include <iomanip>#include <stack>#include <deque>#include <fstream>using namespace std;struct primnode{public:char begvex;char endvex;int lowcost;};struct adknode{int dist;//最近距离char way[50];//顶点数组int nodenum;//经过的顶点数};class Mgraph//邻接矩阵储存结构{public:Mgraph(){}~Mgraph(){}void CreatMGraph();void DFS (int );//用递归实现void DFS1(int );//非递归void BFS(int );void print();void prim();int mini();int low();//最短距离函数的辅助函数int LocateVex(char);void kruskal();void Dijkstra();void Floyd();private:int number;//顶点数目int arcnum;//边的数目char vexs[50];int arcs[50][50];int visited[50];//便利时的辅助工具primnode closeedge[50];//primadknode dist[50];//最短路径int D[20][20];//floyd算法距离int P[20][20][20];//floyd算法路径};int Mgraph::LocateVex(char s){for(int i=0;i<number;i++)if (vexs[i]==s)return i;return -1;}void Mgraph::print(){cout<<"顶点为:";for(int k=0;k<number;k++)cout<<vexs[k];cout<<endl;for(int i=0;i<number;i++){for(int j=0;j<number;j++)cout<<setw(6)<<left<<arcs[i][j]<<" ";cout<<endl;}for(int m=0;m<number;m++)cout<<visited[m];cout<<endl;}void Mgraph::CreatMGraph()//图的邻接矩阵储存结构{char vex1,vex2;int i,j,k,m;cout<<"请输入定点数,边数:"<<endl;cin>>number>>arcnum;cout<<"请输入顶点(字符串类型):"<<endl;for(i=0;i<number;i++)cin>>vexs[i];for(i=0;i<number;i++)for(j=0;j<number;j++)arcs[i][j]=1000;for(k=0;k<arcnum;k++){cout<<"请输入边的两个顶点及边的权值:"<<endl; cin>>vex1>>vex2>>m;i=LocateVex(vex1);j=LocateVex(vex2);arcs[i][j]=m;arcs[j][i]=m;}}void Mgraph::DFS(int i=0)//用递归实现{int j;cout<<vexs[i]<<"------>";visited[i]=1;for (j=0;j<number;j++){if(!(arcs[i][j]==1000)&&!visited[j])DFS(j);}}void Mgraph::DFS1(int i=0)//非递归{stack<int> st;st.push(i);while(!st.empty()){int j=st.top();st.pop();cout<<vexs[j]<<"---->";visited[j]=1;for(int k=0;k<number;k++){if((!(arcs[j][k]==1000))&&!visited[k])st.push(k);}}}void Mgraph::BFS(int i=0)//广度优先遍历{deque<int> de;de.push_back(i);cout<<vexs[i]<<"------>";visited[i]=1;while(!de.empty()){int k=de.front();for(int j=0;j<number;j++){if(arcs[k][j]!=1000&&!visited[j]){cout<<vexs[j]<<"------>";visited[j]=1;de.push_back(j);}}de.pop_front();}}int Mgraph::mini(){static int i;int min=0;for (int j=0;j<number;j++){if(!visited[j]){if (closeedge[min].lowcost>closeedge[j].lowcost){min=j;}}}i=min;cout<<"包括边("<<closeedge[i].begvex<<","<<closeedge[i].endvex<<")"; return i;}void Mgraph::prim(){char u;cout<<"请输入起始顶点:"<<endl;cin>>u;int i=LocateVex(u);visited[i]=1;for(int j=0;j<number;j++){closeedge[j].begvex=u;closeedge[j].endvex=vexs[j]; closeedge[j].lowcost=arcs[i][j];}for (int m=1;m<number;m++){int n=mini();visited[n]=1;closeedge[n].lowcost=1000;for (int p=0;p<number;p++){if(!visited[p]){if(arcs[p][n]<closeedge[p].lowcost){closeedge[p].lowcost=arcs[p][n];closeedge[p].begvex=vexs[n];}}}}}void Mgraph::kruskal(){int a,b,k=0;int min=1000;int arcs1[20][20];for (int m=0;m<number;m++)visited[m]=m;//每一个顶点属于一颗树for (int i=0;i<number;i++)for(int j=0;j<number;j++)arcs1[i][j]=arcs[i][j];while (k<number-1){min=1000;for (int i=0;i<number;i++){for (int j=0;j<number;j++){if (arcs1[i][j]<min){a=i;b=j;min=arcs1[i][j];}}}if (visited[a]!=visited[b]){cout<<"包括边("<<vexs[a]<<","<<vexs[b]<<")";k++;for (int n=0;n<number;n++){if (visited[n]==visited[b])visited[n]=visited[a];}}elsearcs1[a][b]=arcs[b][a]=1000;}}void Mgraph::Dijkstra(){cout<<"请输入起始点"<<endl;char u;cin>>u;int i=LocateVex(u);visited[i]=1;for (int j=0;j<number;j++){dist[j].dist=arcs[i][j];dist[j].nodenum=0;}for (j=1;j<number;j++){int distance=1000;int min=0;for (int n=0;n<number;n++){if(!visited[n]){if (distance>dist[n].dist){distance=dist[n].dist;min=n;}}}int m=min;visited[m]=1;for (n=0;n<number;n++){if(!visited[n]){if((dist[m].dist+arcs[m][n])<dist[n].dist){dist[n].dist=dist[m].dist+arcs[m][n];dist[n].nodenum=0;for (int x=0;x<dist[m].nodenum;x++){dist[n].way[x]=dist[m].way[x];dist[n].nodenum++;}dist[n].way[dist[n].nodenum++]=vexs[m];} } } }//输出功能for (int n=0;n<number;n++){if (n!=i){ if(dist[n].dist<1000){cout<<vexs[i]<<"到"<<vexs[n]<<"的最近距离为:"<<dist[n].dist<<endl;cout<<"经过的顶点为:"<<vexs[i]<<"---->";for (int p=0;p<dist[n].nodenum;p++){ cout<<dist[n].way[p]<<"----->";}cout<<vexs[n]<<endl;}elsecout<<vexs[i]<<"到"<<vexs[n]<<"没有通路"<<endl;} } }void Mgraph::Floyd(){int i,j,m,n;for ( i=0;i<number;i++)for ( j=0;j<number;j++)for (m=0;m<number;m++)P[i][j][m]=0;for ( i=0;i<number;i++)for ( j=0;j<number;j++){D[i][j]=arcs[i][j];if(D[i][j]<1000){P[i][j][i]=1;P[i][j][j]=1;} }for ( i=0;i<number;i++)for ( j=0;j<number;j++)for (m=0;m<number;m++){if (i==j||j==m||i==m)continue;if (D[i][m]+D[m][j]<D[i][j]){D[i][j]=D[i][m]+D[m][j];for (n=0;n<number;n++){P[i][j][n]=P[i][m][n]||P[m][j][n];} } }for ( i=0;i<number;i++)for ( j=0;j<number;j++){if (D[i][j]<1000){cout<<vexs[i]<<"到"<<vexs[j]<<"的最近距离为:"<<D[i][j]<<endl;cout<<"经过的顶点为:";for (m=0;m<number;m++){if (P[i][j][m]){cout<<vexs[m]<<"------>";} }cout<<endl;}elseif (i!=j)cout<<vexs[i]<<"到"<<vexs[j]<<"没有通路"<<endl;}}int main(){Mgraph g;g.CreatMGraph();g.Floyd();return 0;}四、实验结果五、实验总结本次实验主要是学习掌握图的存储结构,学会编写求最短路径的算法。
图的最短路径算法存储结构及其实现
学院实验报告院、系:姓名学号专业、班级课程名称数据结构实验室名称2#101实验名称图的最短路径算法存储结构及其实现指导老师日期、时间2012年6月13日,下午第一节课同组者无天气晴室(气)温 31℃实验报告内容:1.实验目的:本次实验的主要目的是:(1)理解图的最短路径算法的概念;(2)掌握图的最短路径算法存储结构的特点和数据结构的定义;(3)熟练掌握图的最短路径算法存储结构上的实现;(4)通过图的最短路径算法的实际应用,提高学生分析和解决实际问题的能力。
2.实验要求:本实验的内容包括:(1)掌握图的最短路径算法存储结构的基本操作。
(2)主控程序设计;3.实验程序清单:#include <stdio.h>#include <conio.h>#include <stdlib.h>#define X 10000#define VertexNum 7 //实际上共有六个顶点(1---6)#define EdgeNum 9int Graph[VertexNum][VertexNum] =//0 1 2 3 4 5 6{ X, X, X, X, X, X, X, //0X, X, 6, 3, X, X, X, //1X, X, X, X, 5, X, X, //2X, X, 2, X, 3, 4, X, //3X, X, X, X, X, X, 3, //4X, X, X, X, 2, X, 5, //5X, X, X, X, X, X, X //6};int Visited[VertexNum];int path[VertexNum];int Distance[VertexNum];void Dijkstra(int Begin){int MinEdge, Vertex, i,j, Edges;Edges = 1;Visited[Begin] = 1;for (i = 1; i<VertexNum; i++) Distance[i] = Graph[Begin][i];Distance[Begin] = 0;printf(" 1 2 3 4 5 6\\n");printf("************************************\\n");printf("s:%d", Edges);for( i=1; i<VertexNum; i++)if (Distance[i] == X) printf(" *"); else printf("%3d",Distance[i]);printf("\\n");while( Edges<VertexNum-1){Edges++; MinEdge = X;for(j=1; j<VertexNum; j++)if (Visited[j]==0 && MinEdge > Distance[j] ){Vertex = j; MinEdge = Distance[j];}Visited[Vertex] = 1;printf("s:%d",Edges);for(j=1; j<VertexNum; j++){if (Visited[j] == 0 && Distance[Vertex] + Graph[Vertex][j] <Distance[j]) { Distance[j] = Distance[Vertex] + Graph[Vertex][j];path[j] = Vertex;}if (Distance[j] == X) printf(" *"); else printf("%3d",Distance[j]);}printf("\\n");}}void main(){int i;int k;for(i=0; i<VertexNum; i++) { Visited[i] = 0; path[i] = 1;}Dijkstra(1);printf("\\n\\nAll Path***********************\\n");for(i=2; i<VertexNum; i++){printf("[%d] ",Distance[i]);k = i;do{printf("%d<--",k);k = path[k];} while (k!=1);printf("1 \\n");}}4.实验程序执行结果(截图):5.执行结果的分析:先建立图的最短路径算法,键入数据,并进行图的最短路径算法。
最短路径实验报告
D[w] = min+mgraph.arcs[v][w].adj; //更新D[w]
for(j = 0;j<mgraph.vexnum;j++)
//修改P[w],v0到w经过的顶点包括v0到v经过的顶点再加上顶点w
{
P[w][j] = P[v][j];
}
P[w][w] = true;
}
}
}
}
3、运行与测试
for(w = 0;w<mgraph.vexnum;w++)
{
D[v][w] = mgraph.arcs[v][w].adj;//顶点v到顶点w的直接距离
for(u = 0;u<mgraph.vexnum;u++)
{
P[v][w][u] = false;//路径矩阵初值
}
if(D[v][w]<infinity)
//根据新并入的顶点,更新不在S集的顶点到v0的距离和路径数组
{
if(!final[w]&&min<infinity&&mgraph.arcs[v][w].adj<infinity&&
(min+mgraph.arcs[v][w].adj<D[w]))
// w不属于S集且v0→v→w的距离<目前v0→w的距离
程序运行如图所示。
Step1:运行程序,屏幕显示菜单。
Step2:运行功能选择。
Case1:输入“1”,选择菜单项1,进入图的创建操作。
1.1根据屏幕提示,创建有向网。
1.2屏幕显示网信息。
Case2:输入“2”,选择菜单项2,进入求源点到其他各点的距离操作。
