Dijkstra 算法正确性的证明
问题
给定一个非负权边的图,规定起点为uuu,求从uuu出发到每一个节点的最短路径。(求解非负权图上单源最短路径)
流程简述
将结点分成两个集合:已确定最短路长度的点集(记为SSS集合)的和未确定最短路长度的点集(记为TTT集合)。
一开始所有的点都属于TTT集合,dis(s)=0\mathrm{dis}(s) = 0dis(s)=0,其他点的dis\mathrm{dis}dis均为+∞+\infty+∞。
然后重复这些操作:
- 从TTT集合中,选取一个最短路长度最小的结点,移到SSS集合中;
- 对那些刚刚被加入SSS集合的结点的所有在TTT内的邻接点更新dis\mathrm{dis}dis。
直到TTT集合为空,算法结束。
正确性证明
显然,Dijkstra算法的正确性取决于命题「每当一个结点vvv加入SSS集合时,此时dis(v)\mathrm{dis}(v)dis(v)对应的路径r:u→vr : u \rightarrow vr:u→v的长必为全局最短路径长D(v)D(v)D(v)」的真伪。
(反证法)假设存在另一条路径r′:u→vr' : u \rightarrow vr′:u→v为全局最短路径,即
D(v)<dis(v) D(v) < \mathrm{dis}(v) D(<