||
Dijkstra算法概述:
初始时,原点 s 的路径长度值被赋为 0 (d[s] = 0),若存在能直接到达的边(s,m),则把d[m]设为w(s,m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于 V 中所有顶点 v 除 s 和上述 m 外 d[v] = ∞)。
Dijkstra 算法的基础操作是边的拓展:如果存在一条从 u 到 v 的边,那么从 s 到 v 的最短路径可以通过将边(u, v)添加到尾部来拓展一条从 s 到 v 的路径。这条路径的长度是 d[u] + w(u, v)。如果这个值比目前已知的 d[v] 的值要小,我们可以用新值来替代当前 d[v] 中的值。
算法维护两个顶点集 S 和 T。如果某个顶点已经能确定其到源点的最短路径值,那么将其存入集合 S (按Dijkstra算法加入到集合 S中的u点,其当前路径长度必定为最短路径 ,通过反正法证明),而集合 T 则保留其它非S集中的顶点。
当算法退出时(T集为空),d[v] 中存储的便是从 s 到 v 的最短路径,或者如果路径不存在的话是无穷大。
在算法过程中d[v] 值不断逼近最终结果。
下面提供一个例子来形象说明其过程:
图1 带权有向图
0、假设源点为v0,当前探索路径{},v0设为待进入S集的顶点,T集包含所有顶点。
终点 | v1 | v2 | v3 | v4 | v5 |
v0到其它点的最短距离 | ∽ | ∽ | ∽ | ∽ | ∽ |
1、将待进入S的顶点加入S 集,从T集中移走 ,并加入到 当前探索路径的末端。
根据刚进入s集中的顶点和与其联通的顶点,建立临时探索路径如下:
{v0,v2}、{v0,v4}、{v0,v5},并计算出对应的路径长度,
在表格中,根据v2、v4、v5对应的路径长度值的前后大小关系,“选择性”地进行更新,如下表:(只需更新末端点在T中的路径长度,因为按Dijkstra算法加入集合 S中的v点,必定d[v] 的值已经是最短路径,通过反正法证明;也可以试着更新能达到的、但在s中的顶点,结果都是徒然)
终点 | v1 | v2 | v3 | v4 | v5 |
v0到其它点的最短距离 | ∽ | 10 | ∽ | 30 | 100 |
在{v0,v2}、{v0,v4}、{v0,v5}中按路径距离从小到大排序,
结果:{v0,v2}、{v0,v4}、{v0,v5}
循环处理排序后的路径:
如果T为空(最终S集合包含了所有的顶点),跳出循环。
如果该路径末尾端点不在T中,进入下一次循环,
如果该路径末尾端点在T中,该端点定为待进入S的端点,递归进入到第1步;
循环体结束。
1、算法维护两个顶点集 S 和 T。集合 S 是用来保留我们已知到源点最短路径的顶点(既d[u] 已确定的顶点),集合 T 则保留其它非S集中的顶点。集合S初始状态为空,而后每一步都有一个顶点从 T 移动。
2、按Dijkstra算法加入到集合 S中的u点,其当前路径长度必定为最短路径 ,通过反正法证明。
3、在算法过程中不断对源点到还在T集合中各点路径长度进行更新,不断逼近其最终结果 。
4、注意Dijkstra算法中对T非空情况的处理
5、代码实现网上很多。