数据结构-图【荐】.ppt

数据结构-图【荐】.ppt

⑶ 算法分析 设AOE网有n个事件,e个活动,则算法的主要执行是: ◆ 进行拓扑排序:时间复杂度是O(n+e) ; ◆ 求每个事件的ve值和vl值:时间复杂度是O(n+e) ; ◆ 根据ve值和vl值找关键活动:时间复杂度是O(n+e) ; 因此,整个算法的时间复杂度是O(n+e) 。 7.7 最短路径 若用带权图表示交通网,图中顶点表示地点,边代表两地之间有直接道路,边上的权值表示路程(或所花费用或时间) 。从一个地方到另一个地方的路径长度表示该路径上各边的权值之和。问题: ◆ 两地之间是否有通路? ◆ 在有多条通路的情况下,哪条最短? 考虑到交通网的有向性,直接讨论的是带权有向图的最短路径问题,但解决问题的算法也适用于无向图。 将一个路径的起始顶点称为源点,最后一个顶点称为终点。 7.7.1 单源点最短路径 对于给定的有向图G=(V,E)及单个源点Vs,求Vs到G的其余各顶点的最短路径。 针对单源点的最短路径问题,Dijkstra提出了一种按路径长度递增次序产生最短路径的算法,即迪杰斯特拉(Dijkstra)算法。 1 基本思想 从图的给定源点到其它各个顶点之间客观上应存在一条最短路径,在这组最短路径中,按其长度的递增次序,依次求出到不同顶点的最短路径和路径长度。 即按长度递增的次序生成各顶点的最短路径,即先求出长度最小的一条最短路径,然后求出长度第二小的最短路径,依此类推,直到求出长度最长的最短路径。 2 算法思想说明 设给定源点为Vs,S为已求得最短路径的终点集,开始时令S={Vs} 。当求得第一条最短路径(Vs ,Vi)后,S为{Vs,Vi} 。根据以下结论可求下一条最短路径。 设下一条最短路径终点为Vj ,则Vj只有: ◆ 源点到终点有直接的弧Vs,Vj; ◆ 从Vs 出发到Vj 的这条最短路径所经过的所有中间顶点必定在S中。即只有这条最短路径的最后一条弧才是从S内某个顶点连接到S外的顶点Vj 。 若定义一个数组dist[n],其每个dist[i]分量保存从Vs 出发中间只经过集合S中的顶点而到达Vi的所有路径中长度最小的路径长度值,则下一条最短路径的终点Vj必定是不在S中且值最小的顶点,即: dist[i]=Min{ dist[k]| Vk∈V-S } 利用上述公式就可以依次找出下一条最短路径。 3 算法步骤 ① 令S={Vs} ,用带权的邻接矩阵表示有向图,对图中每个顶点Vi按以下原则置初值: Wsi i≠s且vs,vi∈E, wsi为弧上的权值 ∞ i≠s且vs,vi不属于E dist[i]= 0 i =s ② 选择一个顶点Vj ,使得: dist[j]=Min{ dist[k]| Vk∈V-S } Vj就是求得的下一条最短路径终点,将Vj 并入到S中,即S=S∪{Vj} 。 ③ 对V-S中的每个顶点Vk ,修改dist[k],方法是: 若dist[j]+Wjkdist[k],则修改为: dist[k]=dist[j]+Wjk (?Vk∈V-S ) ④ 重复②,③,直到S=V为止。 4 算法实现 用带权的邻接矩阵表示有向图, 对Prim算法略加改动就成了Dijkstra算法,将Prim算法中求每个顶点Vk的lowcost值用dist[k]代替即可。 ◆ 设数组pre[n]保存从Vs到其它顶点的最短路径。若pre[i]=k,表示从Vs 到Vi的最短路径中,Vi的前一个顶点是Vk,即最短路径序列是(Vs , …, Vk , Vi) 。 ◆ 设数组final[n],标识一个顶点是否已加入S中。 算法实现的关键 待求点的最短路径长度本身就是待求的,又如何找出其中的最短呢? BOOLEAN final[MAX_VEX] ; int pre[MAX_VEX] , dist[MAX_VEX] ; void Dijkstra_path (AdjGraph *G, int v) /* 从图G中的顶点v出发到其余各顶点的最短路径 */ { int j, k, m, min ; for ( j=0; jG-vexnum; j++) { pre[j]=v ; final[j]=FALSE ; dist[j]=G-adj[v][j] ; } /* 各数组的初始化 */ dist[v]=0 ; final[v]=TRUE ; /* 设置S={v} */ for ( j=0; jG-vexnum-1; j++) /* 其余n-1个顶点 */ { m=0 ; while (final[m])

文档评论(0)

1亿VIP精品文档

相关文档