两种单源最短路径算法及其正确性证明
(一)前言
网上已经有很多关于$Dijkstra$和$Bellman–Ford–Moore$算法的文章了,为何在此还要再写?其实不难发现,常见的教程都是给出了算法的步骤与所谓的实现代码,但要找到关于其为何正确这一点的说明是不太见到的(或者是证明存在一定问题,大多数是细节交代不清或者疯狂跳步),这就很捉鸡了。本文参考了一些文献,最终选择将[2]中关于此部分的内容讲解翻译过来(结合实际情况做一定调整,并将逻辑跳跃的地方补充),我认为还是比较通俗易懂的,不像某法导论上的证明黑压压一片,令人智熄。总而言之,至少保证数学上是完备的,在此分享
(二)符号与概念
令$G$为连通有向图,其每一条有向边被赋予有限实数值,该值称为该条有向边的长度
从顶点$i$到顶点$j$的有向边长度记做$w(i,j)$,若顶点$i$与顶点$j$没有有向边连接,此时$w(i,j)=\infty$
若图$G$中有一条有向路径$P$,则将该条路径上所有有向边的长度之和称为其长度
将在所有以$s$为起点、以$t$为终点的有向路径中,长度最小的路径称为$s-t$最短路径
对于顶点$s$与顶点$t$,若存在$s-t$最短路径,则称路径长度为$s$到$t$的距离,记做$d(s,t)$
为了便于讨论,将图$G$上的顶点分别记做$1,2,...n$
(三)问题与假定
首先,先阐述什么是单源最短路径($Single-source$ $Shortest$ $Paths$)问题
- 对于图$G$中的某一个顶点$i$,找出它到图上任意一个顶点$j$的$i-j$最短路径
接着,为了方便后续算法的讨论,此处需要做出一些不失一般性的假设
- 默认顶点$1$是给定的那个顶点$i$,即算法最终要找到所有顶点到顶点$1$的最短路径
- 映射$\lambda:顶点集\Rightarrow R$,记录算法迭代过程中$1-k$最短路径长度的更新值$(k\in \{1,2,...,n\})$
- 初始情况下,$\lambda(1)=0$且$\lambda(i)=\infty(i\ne 1)$,且算法最终要求在迭代结束时$d(1,i)=\lambda(i)$
- 假定顶点$1$可以到达图$G$上的任意一点,即算法结束后$\lambda(i)$都为有限值
- 图$G$中不存在一个有向圈,使得圈上所有有向边的长度之和为负,下图的几种结构都是不被允许的
(四)最优性条件($Optimality$ $Conditions$)
【定理】设连通有向图$G=(V,E)$,每条边$e\in E$被赋予一个有限实数$w(e)$,记$\lambda(i)(i \geq 1)$为$1-i$有向路径长度
对于任意的$i\geq 1$:$\lambda(i)=d(1,i)\Leftrightarrow \forall e=(i,j)$都有$\lambda(i)+w(i,j)\geq \lambda(j)$
【证明】由于$\lambda(j)(j \geq 1)$是顶点$1$到顶点$j$的距离,若存在某条边$e=(i,j)$使得$\lambda(i)+w(e)<\lambda(j)$
先取路径$1-i$最短路径,再添加边$e$后则获得了比长度比$\lambda(i)$还小的$1-j$路径,与$\lambda(j)=d(1,j)$矛盾
必要性成立,下说明充分性:考虑某条从顶点$1$到顶点$j$的有向路径$P:1=i_0,i_1,...,i_{k-1},i_k=j$
若最优性条件成立,则$\lambda(j)=\lambda(i_k)\leq \lambda(i_{k-1})+w(i_{k-1},i_k)\leq ... $
$\leq \lambda(i_0)+\sum_{t=1}^k w(i_{t-1},t_t)=\sum_{t=1}^k w(i_{t-1},t_t)=P的长度$
此时,由于$P$的任意性可知,$\lambda(j)$是所有$1-j$路径长度中最小的,即$\lambda(j)=d(1,j)$
(五)无负权边的SSP问题——$Dijkstra$算法
$Dijkstra$算法的过程为按照一定的规则对所有顶点进行遍历检查
初始化规定$\lambda(1)=0$且$\lambda(i)=\infty(i\ne 1)$,所有的点的标记状态都是“未标记”
以第$i$轮迭代为例:
- 在图$G$中所有未被标记的点中,选择$\lambda$最小的顶点做标记,记为$u_i$
- 对所有边$(u_i,j)$检查是否违背最优性条件,其中$j$是$G$中未被标记的顶点
- 若存在某一个$(u_i,j)$违反最优性条件,则$\lambda(j)$更新为$\lambda(u_i)+w(u_i,j)$,且记录更新$j$的顶点为$u_i$
由上述过程可见,算法进行时需要三个列表存储每个顶点的信息:
- $[\lambda]$记录顶点每轮迭代的路径长度
- $[PREM]$记录每一个顶点被标记的情况,初始化时为全零数组,在遍历中到达某顶点$i$后,$PREM_i$则被标记为$1$
- $[PRED]$记录每个顶点的$\lambda$值被哪一个标记点所更新
完整流程如下:
两个事实:
- 一旦某个顶点被标记后,它的$\lambda$值就不会再改变
- 若下面的定理成立且顶点$v$被标记,那么$v,PRED(v),PRED(PRED(V)),...,1$是一条$1-v$最短路径
【$Dijkstra$定理】令$u_i(i\geq 1)$为第$i$轮中的新标记点,且$d(u_i)$是最终$u_i$的$\lambda$值,则$d(1,u_i)=d(u_i)$
在证明上述定理之前,先叙述并证明下面的引理:
【引理】$d(u_1) \leq d(u_2) \leq ... \leq d(u_n)$
【证明】令$S_i$为在第$i$轮迭代结束时,所有被标记的点的集合,记为$S_i=\{u_1,u_2,...,u_i\}$
此时,设顶点$j\notin S_i$,若$\lambda(j)$是有限数,那么$\lambda(j)\leq d(u_k)+w(u_k,j)(\forall k\leq i,\forall j \notin S_i)$
这是因为$\lambda(j)$如果是有限数,说明已经被与它相邻的标记点扫描到了,且必然取的是最小的那个更新
设$u_{i+1}$是下一轮迭代被标记的点,此时$\lambda(u_{i+1})=d(u_{i+1})\leq d(u_k)+w(u_k,u_i+1)(\forall k\leq i)$
设$u_a=PRED(u_{i+1})$,因为$d(u_{i+1})$不再改变,故由上式得$d(u_{i+1}) = d(u_a)+w(u_a,u_i+1)$
当$a=i$时,立即得到$d(u_i)\leq d(u_{i+1})$
当$a<i$时,顶点$u_{i+1}$必然在第$a$轮时已经取到了最终值$d(u_{i+1}) = d(u_a)+w(u_a,u_i+1)$
那么,在第$i$轮时这个式子仍然成立,但是由于标记点选择的是$u_i$而不是$u_{i+1}$,故$d(u_i)\leq d(u_{i+1})$
由$i$的任意性可知,命题成立
下面证明$Dijkstra$定理:
【证明】只需说明$d(u_i)$满足最优性条件即可:下面考察任意一条边$(u_i,u_j)(i\ne j)$
若$i>j$,则由引理可知$d(u_j)\leq d(u_{i}) \leq d(u_i)+w(u_i,u_j)$
若$i<j$,式子$\lambda(j)\leq d(u_k)+w(u_k,j)(\forall k\leq i,\forall j \notin S_i)$成立
且由$\lambda(j)$的不增性,得$d(u_j)\leq \lambda(j) \leq d(u_i)+w(u_i,u_j)$
此时,由边的任意性知定理成立
上面的所有叙述都基于无负权边的假定,下图直观地说明这个假定的必要性:
(六)带负权边的SSP问题——$Bellman–Ford–Moore$算法
首先,给出完整算法流程:
从上图可见,BFM算法就是暴力搜索边是否违背最优性条件,该算法能够终止的原因如下:
- 每一次更新$\lambda$的值,只与被更新的顶点有关,即对于其他顶点的情况不会变得更差
- 更新$\lambda$的值等价于更新路径,而两点之间路径数量是有限的(不考虑回路)
虽然算法能够终止 ,但是显然随着顶点数量的增加,其复杂度会指数级增长
下面给出一种$O(mn)$复杂度的改进BFM算法,它包含三个步骤:
- Step1: 按任意顺序指定一组边$\{e_1,e_2,...,e_m\}$
- Step2: 按上述顺序检查并更新$\lambda_i(i \in \{1,2,...,n\})$
- Step3: 若没有$\lambda$被更新,则算法结束,反之重复Step2
其复杂度为$O(mn)$的原因:如下定理保证了算法至多在$n-1$轮内结束(最短路径最多有$n-1$条边)
【定理】若存在$1-j$最短路径,且该路径共计包含$k$条边,则$\lambda(j)$在第$k$轮检查后必达到终值
【证明】对$k$使用归纳法,当$k=1$时显然成立
考虑$1-j$最短路径$P:1,i_1,...,i_k,i_{k+1}=j$,由于$P’:1,i_1,...,i_k$是具有$k$条边的$1-i_k$最短路径
由归纳假设,$\lambda_{i_k}$在第$k$轮已经取到终值,故在下一轮$i_{k+1}$的$\lambda$值被更新为$\lambda_{i_k}+w(i_k,i_{k+1})$
即在第$k+1$轮,$\lambda(j)=d(1,j)$取到终值
重新回到上面的例子,不难发现$BFM$算法能够解决负权边的问题:
- 选择边$(1,3),(2,3),(1,2)$为检查顺序
- 第$1$轮:$\lambda(1)=0,\lambda(2)=3,\lambda(3)=1$
- 第$2$轮:$\lambda(1)=0,\lambda(2)=3,\lambda(3)=0$
此外,$BFM$算法还可以用于负圈检测:
- 令$C$为图$G$所有有向边长度绝对值中的最大值,显然有负圈则算法不终止
- 由于最短路的边数不会达到$n$,故若有顶点的$\lambda$值小于$-nC$ ,则算法停止
- 根据该顶点及其$PRED$顶点一路查找就可以检索出一个负圈
(七)参考资料
- Thomas H. Cormen等. Introduction to Algorithms (Third Edition). 2009
- Subramanian Arumugam等. Handbook of Graph Theory, Combinatorial Optimization, and Algorithms. 2016
- Martin Charles Golumbic等. Graph Theory, Combinatorics and Algorithms: Interdisciplinary Applications. 2005
【附】链接: https://pan.baidu.com/s/1WZnWLXlxfcV6IztnTrh57g 密码: e1gi