一、前言
在离散数学的学习过程中,遇到了最短路径问题。Dijkstra算法求解单源最短路径本身不易理解,本文综合自己的理解试图给出Dijkstra算法形式化描述以及示例。
二、相关概念
最短路径问题:给定带权图G=<V,E,W>及节点u和v,其中每一条边e的权重W(e)为非负数,求从u到v的最短路径。
最短路径性质:如果 是从u到v的最短路径,则对每一个 , 是 的最短路径。(用土话讲就是,最短路径上的任意两点之间的路径也是最短的)
三、Dijkstra算法描述
算法步骤:
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中
四、示例
带权图G如图1-1所示,求从到其余各顶点的最短路径和距离。
图1-1
使用dist数组表示各顶点到v1顶点的路径长度,则初始时dist=[0, 3, 7, 5, ,,]
使用S表示已选节点,T表示未选节点,则初始时S={},T={}
第一步,在T集合中挑选出与源点距离最短的顶点v2,并修改dist中以v2为中间点后各顶点的最短距离。则
S= {v1,v2} T={v3,v4,v5,v6,v7}
dist=[0,3,5,5,9,,]
第二步,在T中挑选出与源点距离最短的顶点v3,并修改dist中以v3为中间点后各顶点的最短距离。则
S={v1,v2,v3} T= {v4, v5, v6, v7}
dist = [0, 3, 5, 5, 8, , ]
第三步,在T中挑选出与源点距离最短的顶点v4, 并修改dist中以v4为中间点后各顶点的最短距离。则
S={v1,v2,v3,v4}, T= {v5, v6, v7}
dist = [0, 3, 5, 5, 8, 7, 13]
第四步,在T中挑选与源点距离最短的顶点v5, 并修改dist中以v5为中间点后各顶点的最短距离。则
S={v1, v2, v3, v4, v5}, T= {v6, v7}
dist=[0, 3, 5, 5, 8, 7, 10]
第五步,在T中挑选出与源点距离最短的顶点v6, 并修改dist中以v6为中间点后各顶点的最短距离。则
S= {v1, v2, v3, v4, v5, v6}, T= {v7}
dist=[0, 3, 5, 5, 8, 7, 9]
第六步,在T中挑选出与源点距离最短的顶点v7, 并修改dist中以v7为中间点后各顶点的最短距离。则
S= {v1, v2, v3, v4, v5, v6, v7}, T= {}
dist=[0, 3, 5, 5, 8, 7, 9]
此时,由于T集合为空,整个算法到此结束。
五、Java版Dijkstra算法
略