算法思想
符号约定
设 表示 与 之间的边的边权。 分别为源点、终点。
基本过程
维护集合 . 为已找到最短路的点, 为剩余的点。最初,仅有源点 位于 内。设所有的点有标记 ,.
首先进行初始化:, .
迭代以下过程直至 加入集合 :
- 对所有 中已赋过 值的元素 ,选出 中目前 值最小的元素 ,并且将其移入集合 .
- 如下更新与 相连的所有元素的 值:,如果 尚无 值或 ,更新 为 ;否则保持 不变。
个人理解
对更新 值过程的说明
其实是一个猴子选带王的过程
本质上是符合以下条件的路径中,最短路的长:, where , 是待研究的点。(说人话:先走包含于 中的路径,**最后一步** 跳到待研究点)每次扩张集合 之后,都要问一问:如果以新加入点为跳板, 值能不能进一步减小?
注释:已经在 中的结点具有“ 值即为从 到它最短路的长”的性质(将在下文说明理由),这使得我们可以通过 来计算以 为最后一步“跳板”的路径中,最短路的长。
通过这样的过程,我们可以保证, 值维护了“先走 中路径,最后一步再到 ”的所有路径中,最短路的长度。
为什么 中节点的 值就是源点到它的最短路长度呢?
关键在于“选出 中 值最小的元素移入 ”这一步!
下面证明: 中 值最小的元素 ,其 值就是 到 的最短路的长度。
由于源点 ,能够到达 的路径可以分为两类:
也就是说,第二类路径除了 外的点全都在 中,而第一类路径只有开头的一小段在 中,并于 拐到 外,后面的随意。
显然,对于 是第二类路径中路径长的最小值(这正是前文叙述的 的含义)。对于第一类路径,假设存在一条路 , where , ,且它的总长 比 小。那么路径 的长度 . 然而, 描述的路径也是“前面都走 中元素,最后一步到 外”类型的路径,于是 **大于等于** ,那么 ,这与“ 值最小”是矛盾的。因此, 就是所有到达 的路径中,最短路的长度。
递归证明
由于初始化后, 是满足“ 中元素 值即为最短路长”的性质,, 的操作满足 值的定义,迭代时选出 中目前 值最小的元素 ,并且将其移入集合 没有破坏“ 中元素 值即为最短路长”的性质;进而本次迭代中对 的更新是合理的。
如是,每一次迭代都维护了这两个性质,递归证明成立。
边权为正
是为了使上一节中的论证成立。
Last modified on 2020-05-14