在许多路由问题中,寻找图中一个顶点到另一个顶点的最短路径或最小带权路径是非常重要的提炼过程。正式表述为,给定一个带权有向图G = (V, E)
, 顶点s
到v
中顶点t
的最短路径为在边集E
中连接s
到t
代价最小的路径。要做到这一点首先要解决更为一般的单源最短路径问题。在单源最短路径问题中,计算从一个起始顶点s
到其他与之相邻顶点之间的最短路劲。
Dijkstra算法##
解决单源最短路径问题的方法之一就是Dijkstra
算法。Dijkstra
算法会生成一颗最短路径树,树的根为起始顶点s
, 树的分支为从顶点s
到图G
中所有其他顶点的最短路径。此算法要求图中的所有权值均为非负数。与Prim
算法类似,Dijkstra
算法也采用贪心算法,它总是将当前看起来最近的最短的边加入最短路径中。
从根本上来说,Dijkstra
算法通过选择一个顶点,并不断探测与之相关的边,类似广度优先搜索,找出当前距离最近的点。
结合下图简要的说一下算法运行过程:
Dijkstra
算法代码实现流程大概如下:
1 function Dijkstra(Graph, source):
2
3 create vertex set Q
4
5 for each vertex v in Graph: // Initialization
6 dist[v] ← INFINITY // Unknown distance from source to v
7 prev[v] ← UNDEFINED // Previous node in optimal path from source
8 add v to Q // All nodes initially in Q (unvisited nodes)
9
10 dist[source] ← 0 // Distance from source to source
11
12 while Q is not empty:
13 u ← vertex in Q with min dist[u] // Source node will be selected first
14 remove u from Q
15
16 for each neighbor v of u: // where v is still in Q.
17 alt ← dist[u] + length(u, v)
18 if alt < dist[v]: // A shorter path to v has been found
19 dist[v] ← alt
20 prev[v] ← u
21
22 return dist[], prev[]