Dijkstra
算法能够求解无负权图(连通图、有向或无向)的单源最短路径(确定起始节点到所有其他节点的最短路径长度)
双向Dijkstra
算法通过从起点(正向搜索)和终点(反向搜索)同时进行Dijkstra
搜索,直到两个搜索的前沿相遇。相遇时,最短路径为正向路径与反向路径之和的最小值
- 算法的适用条件与
Dijkstra
算法相同,通过减少搜索范围提升效率,尤其适用于大规模图
一、核心步骤
论文中对算法的核心步骤进行了口语化描述(Verbal description
)及符号化描述(Symbolic description
),本文合二为一进行描述
1.1、步骤描述
初始化:起点 s s s到各个节点的距离 S ( i ) S(i) S(i),各个节点到终点 t t t的距离 T ( i ) T(i) T(i),各个节点的上游节点 P ( i ) P(i) P(i)、各个节点的下游节点 Q ( i ) Q(i) Q(i)
步骤1:对于某个迭代过程(当前时刻),比较起点 s s s到其他节点的距离 S ( i ) S(i) S(i)与其他节点到终点 t t t的距离 T ( i ) T(i) T(i),确定需拓展的节点(若存在多个则都拓展)
- 若
s
s
s出发到节点
i
i
i的距离最短(
M
i
n
S
(
i
)
≤
M
i
n
T
(
j
)
Min S(i) \le Min T(j)
MinS(i)≤MinT(j)),对于与
i
i
i相邻的节点,判断距离是否需要更新(与
Dijkstra
更新逻辑相同)- 对于 i i i的相邻节点 m m m,若 S ( m ) > d i , m + S ( i ) S(m)>d_{i,m} + S(i) S(m)>di,m+S(i),则 S ( m ) = d i , m + S ( i ) S(m)=d_{i,m} + S(i) S(m)=di,m+S(i),并且更新 m m m的上游节点为 i i i( P ( m ) = i P(m)=i P(m)=i,用于确定最短路上的节点)
- 更新从 s s s出发到其他节点的距离最短值( x = M i n S ( i ) x=Min S(i) x=MinS(i),使用 i i i标识其他节点)
- 若节点
j
j
j到达
t
t
t的距离最短(
M
i
n
S
(
i
)
>
M
i
n
T
(
j
)
Min S(i) > Min T(j)
MinS(i)>MinT(j)),对于与
j
j
j相邻的节点,判断距离是否需要更新
- 对于 j j j的相邻节点 n n n,若 T ( n ) > d n , j + T ( j ) T(n)>d_{n,j} + T(j) T(n)>dn,j+T(j),则 T ( n ) > d n , j + T ( j ) T(n)>d_{n,j} + T(j) T(n)>dn,j+T(j),并且更新 n n n的下游节点为 j j j( Q ( n ) = j Q(n)=j Q(n)=j,用于确定最短路上的节点)
- 更新从其他节点到 t t t的距离最短值( y = M i n T ( j ) y=Min T(j) y=MinT(j),使用 j j j标识其他节点)
步骤2:对于某个迭代过程,比较 s s s到节点 i i i的距离与节点 i i i到 t t t的距离之和 S ( i ) + T ( i ) S(i)+T(i) S(i)+T(i) 与 s s s到其他节点的距离最短值与其他节点到 t t t距离的最短值之和 M i n S ( i ) + M i n T ( i ) Min S(i)+Min T(i) MinS(i)+MinT(i)
- 若 M i n ( S ( i ) + T ( i ) ) ≤ M i n S ( i ) + M i n T ( i ) Min (S(i)+T(i)) \le Min S(i) + Min T(i) Min(S(i)+T(i))≤MinS(i)+MinT(i),则找到最短路(算法终止),根据 P ( i ) P(i) P(i)、 Q ( i ) Q(i) Q(i)确定完整的路径
- 说明:
- 不等式左侧的 S ( i ) + T ( i ) S(i)+T(i) S(i)+T(i)针对的是同一个节点 i i i,即正向( s s s到该节点)、反向(该节点到 t t t)都被搜索过的节点,意味着找到一条完整的路径 s . . . i . . . t s...i...t s...i...t
-
M
i
n
(
S
(
i
)
+
T
(
i
)
)
Min (S(i)+T(i))
Min(S(i)+T(i))即多条完整路径中距离最短的路径,可在迭代时进行更新(避免额外记录所有完整的路径)
- s s s到 t t t的最短距离(完整路径)记为 μ \mu μ,迭代找到新的完整路径时,若 μ > M i n ( S ( i ) + T ( i ) ) \mu>Min (S(i)+T(i)) μ>Min(S(i)+T(i)),则 μ = M i n ( S ( i ) + T ( i ) ) \mu=Min (S(i)+T(i)) μ=Min(S(i)+T(i))
- 不等式右侧的 S ( i ) S(i) S(i)与 T ( i ) T(i) T(i)只是泛指 s s s到其他节点的距离、其他节点到 t t t的距离(一般不是同一个节点)
- M i n S ( i ) + M i n T ( i ) Min S(i) + Min T(i) MinS(i)+MinT(i)表示 s s s到其他节点的距离最短值与其他节点到 t t t距离的最短值之和
1.2、示例
以论文中所给的图为例进行算法步骤说明:起点1、终点9,各条边双向距离相等,例如 d 1 , 2 = d 2 , 1 = 3 d_{1,2}=d_{2,1}=3 d1,2=d2,1=3,图中 d 2 , 3 = 1 d_{2,3}=1 d2,3=1
- 以 ( r , x ) (r,x) (r,x)的形式进行记录,其中 r r r为节点编号, x x x为起点到节点的距离(或节点到终点的距离)
- 对于节点1,为 ( 1 , 0 ) (1,0) (1,0),对于节点9,为 ( 9 , 0 ) (9,0) (9,0)
第1次迭代:节点1、9都需要拓展,拓展后如下图所示
第2次迭代: M i n S ( 2 ) > M i n T ( 6 ) = M i n T ( 8 ) Min S(2)>Min T(6)=Min T(8) MinS(2)>MinT(6)=MinT(8),节点6、8需拓展,拓展后如下图所示(节点6、8之间不连接是因为不满足更新条件)
- 节点3、4被正向、反向搜索过,意味着找到了完整的路径,根据 P ( i ) P(i) P(i)、 Q ( i ) Q(i) Q(i)确定路径为1-3-6-9、1-4-7-9
- 路径1-3-6-9长度为10,路径1-4-6-9长度为12,则 μ = 10 , x = 3 , y = 3 \mu=10, x=3, y=3 μ=10,x=3,y=3(对应节点2、5)
- 因为
10
>
3
+
3
10>3+3
10>3+3,所以继续迭代(因为可能有更短的路径未被搜索到)
第3次迭代: M i n S ( 2 ) = M i n T ( 5 ) Min S(2)=Min T(5) MinS(2)=MinT(5),节点2、5需拓展,拓展后如下图所示
- 拓展节点2
- 新增完整路径1-2-5-8-9,长度为10, μ = 10 \mu=10 μ=10保持不变
- 新增完整路径1-2-3-6-9(原有路径1-3-6-9,节点3距离更新),长度为8, μ = 8 \mu=8 μ=8(距离更新)
- 拓展节点5
- T ( 2 ) = 7 T(2)=7 T(2)=7,无新增完整路径,, μ = 8 \mu=8 μ=8保持不变, x = 4 , y = 4 x=4, y=4 x=4,y=4(对应节点3、3)
- 因为
8
=
4
+
4
8=4+4
8=4+4,所以迭代结束(已找到最短的路径1-2-3-6-9)
二、正确性证明
只要一直迭代(章节1.2的步骤1), S ( i ) S(i) S(i)与 T ( i ) T(i) T(i)就会逐渐接近并达到实际的最短距离,若节点 r r r在 s s s到 t t t的最短路上,则 S ( r ) + T ( r ) S(r)+T(r) S(r)+T(r)就是最短路的长度
论文给出了明确的终止条件能够避免无谓的迭代(“早停”),需要证明 S ( r ) + T ( r ) = M i n ( S ( i ) + T ( i ) ) ≤ M i n S ( i ) + M i n T ( i ) S(r)+T(r)=Min (S(i)+T(i)) \le Min S(i) + Min T(i) S(r)+T(r)=Min(S(i)+T(i))≤MinS(i)+MinT(i)时,路径 s . . . r . . . t s...r...t s...r...t就是全局最短路,即其他路径的长度都不低于 S ( r ) + T ( r ) S(r)+T(r) S(r)+T(r)
为了描述证明过程,对首次满足终止条件时的关键值进行说明:
- s s s到其他节点的最短距离为 x ′ x' x′,其他节点到 t t t的最短距离为 y ′ y' y′
- 对于节点
i
i
i,
s
s
s到
i
i
i距离为
S
′
(
i
)
S'(i)
S′(i),
i
i
i到
t
t
t的距离为
T
′
(
i
)
T'(i)
T′(i),
s
s
s到
i
i
i的最短距离为
S
ˉ
(
i
)
\bar{S}(i)
Sˉ(i),
i
i
i到
t
t
t的最短距离为
T
ˉ
(
i
)
\bar{T}(i)
Tˉ(i)
- 若 S ′ ( i ) > S ˉ ( i ) S'(i)>\bar{S}(i) S′(i)>Sˉ(i),说明正向未迭代到最优,若 T ′ ( i ) > T ˉ ( i ) T'(i)>\bar{T}(i) T′(i)>Tˉ(i),说明反向未迭代到最优
若能证明 S ′ ( r ) + T ′ ( r ) = M i n ( S ′ ( i ) + T ′ ( i ) ) ≤ M i n S ′ ( i ) + M i n T ′ ( i ) = x ′ + y ′ S'(r)+T'(r)=Min (S'(i)+T'(i)) \le Min S'(i) + Min T'(i)=x'+y' S′(r)+T′(r)=Min(S′(i)+T′(i))≤MinS′(i)+MinT′(i)=x′+y′时, S ˉ ( i ) + T ˉ ( i ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i)\ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)≥S′(r)+T′(r),即说明 s . . . r . . . t s...r...t s...r...t就是全局最短路
- 证明思路:按照 S ′ ( i ) S'(i) S′(i)与 x ′ x' x′、 T ′ ( i ) T'(i) T′(i)与 y ′ y' y′的大小关系划分不同情形,若不同情形下结论都成立,则结论具有完备性
2.1、case 1分析
case 1: S ′ ( i ) ≤ x ′ S'(i) \le x' S′(i)≤x′ 且 T ′ ( i ) ≤ y ′ T'(i) \le y' T′(i)≤y′
证明:
- 对于
S
′
(
i
)
≤
x
′
S'(i)\le x'
S′(i)≤x′,若之后继续迭代(假设
x
′
x'
x′对应的节点为
k
k
k),只有当
i
i
i与
k
k
k相邻且
S
′
(
i
)
>
d
k
,
i
+
S
′
(
k
)
=
d
k
,
i
+
x
′
S'(i)>d_{k,i}+S'(k)=d_{k,i}+x'
S′(i)>dk,i+S′(k)=dk,i+x′(显然不成立)时,才会更新
S
(
i
)
S(i)
S(i)
- 因此当 S ′ ( i ) ≤ x ′ S'(i)\le x' S′(i)≤x′时, S ( i ) S(i) S(i)不会再更新,即此时的 S ′ ( i ) = S ˉ ( i ) S'(i)=\bar{S}(i) S′(i)=Sˉ(i),说明正向迭代到最优
- 同理, T ′ ( i ) = T ˉ ( i ) T'(i)=\bar{T}(i) T′(i)=Tˉ(i),说明反向迭代到最优,此时 s . . . i . . . t s...i...t s...i...t为一条完整路径
- 因为 S ′ ( r ) + T ′ ( r ) = M i n ( S ′ ( i ) + T ′ ( i ) ) S'(r)+T'(r)=Min (S'(i)+T'(i)) S′(r)+T′(r)=Min(S′(i)+T′(i)),则 S ˉ ( i ) + T ˉ ( i ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i)\ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)≥S′(r)+T′(r),核心是取了最小值(迭代时更新 s s s到 t t t的最短距离)
- 结论成立
2.2、case 2分析
case 2: S ′ ( i ) > x ′ S'(i) > x' S′(i)>x′ 且 T ′ ( i ) > y ′ T'(i) > y' T′(i)>y′
证明:
- 对于
S
′
(
i
)
>
x
′
S'(i)> x'
S′(i)>x′,若之后继续迭代(假设
x
′
x'
x′对应的节点为
k
k
k),只有当
i
i
i与
k
k
k相邻且
S
′
(
i
)
>
d
k
,
i
+
S
′
(
k
)
=
d
k
,
i
+
x
′
>
x
′
S'(i)>d_{k,i}+S'(k)=d_{k,i}+x'>x'
S′(i)>dk,i+S′(k)=dk,i+x′>x′时,才会更新
S
(
i
)
S(i)
S(i)
- 不论更新与否,都满足 S ′ ( i ) > x ′ S'(i) > x' S′(i)>x′,因此 S ˉ ( i ) > x ′ \bar{S}(i)> x' Sˉ(i)>x′
- 同理, T ˉ ( i ) > y ′ \bar{T}(i)> y' Tˉ(i)>y′
- 则 S ˉ ( i ) + T ˉ ( i ) > x ′ + y ′ = M i n S ′ ( i ) + M i n T ′ ( i ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i)>x'+y'=Min S'(i) + Min T'(i) \ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)>x′+y′=MinS′(i)+MinT′(i)≥S′(r)+T′(r)
- 结论成立
2.3、case 3分析
case 3: S ′ ( i ) ≤ x ′ S'(i) \le x' S′(i)≤x′ 且 T ′ ( i ) > y ′ T'(i) > y' T′(i)>y′
case 4: S ′ ( i ) > x ′ S'(i) > x' S′(i)>x′ 且 T ′ ( i ) ≤ y ′ T'(i) \le y' T′(i)≤y′
说明:case 3与case 4本质相同,因为只需要将 s s s与 t t t交换一下,因此只证明case 3
首先证明一个前置结论:
- 假设节点 i i i到 t t t的全局最短路为 P i t P_{it} Pit,其上的节点依次 b 1 , b 2 , . . . , b l b_1,b_2,...,b_l b1,b2,...,bl,其中 b 1 = i , b l = t b_1=i,b_l=t b1=i,bl=t,则一定存在一个节点 b w b_w bw( 1 < w ≤ l 1<w \le l 1<w≤l),使 T ˉ ( b w − 1 ) > y ′ \bar{T}(b_{w-1})>y' Tˉ(bw−1)>y′ 且 T ˉ ( b w ) ≤ y ′ \bar{T}(b_{w}) \le y' Tˉ(bw)≤y′,即 T ˉ ( b j ) > y ′ , 1 ≤ j ≤ w − 1 \bar{T}(b_j)> y',1 \le j \le w-1 Tˉ(bj)>y′,1≤j≤w−1 且 T ˉ ( b j ) ≤ y ′ , w ≤ j ≤ l \bar{T}(b_j)\le y',w \le j \le l Tˉ(bj)≤y′,w≤j≤l,( b w b_w bw是最后一个反向迭代到最优的节点)
证明:
- 对于 P i t P_{it} Pit上的节点 j j j, T ˉ ( j ) = T ˉ ( j + 1 ) + d j , j + 1 \bar{T}(j)=\bar{T}(j+1)+d_{j,j+1} Tˉ(j)=Tˉ(j+1)+dj,j+1,因此 T ˉ ( j ) > T ˉ ( j + 1 ) \bar{T}(j)> \bar{T}(j+1) Tˉ(j)>Tˉ(j+1)(单调递减)
- 对于节点 i i i, T ′ ( i ) > y ′ T'(i) > y' T′(i)>y′,因此 T ˉ ( i ) > y ′ \bar{T}(i) > y' Tˉ(i)>y′;对于节点 t t t, T ˉ ( t ) = 0 < y ′ \bar{T}(t)=0<y' Tˉ(t)=0<y′
- 因此,一定存在一个节点 b w b_w bw( 1 < w ≤ l 1<w \le l 1<w≤l),使 T ˉ ( b w − 1 ) > y ′ \bar{T}(b_{w-1})>y' Tˉ(bw−1)>y′ 且 T ˉ ( b w ) ≤ y ′ \bar{T}(b_{w}) \le y' Tˉ(bw)≤y′
- 结论成立
在前置结论的基础上证明 S ˉ ( i ) + T ˉ ( i ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i) \ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)≥S′(r)+T′(r),考虑3种相互排斥的情形,若不同情形下结论都成立,则结论具有完备性
2.3.1、case A分析
case A:存在一个节点 b v b_v bv( w ≤ v ≤ l w \le v \le l w≤v≤l), S ′ ( b v ) ≤ x ′ S'(b_v) \le x' S′(bv)≤x′
证明:
-
对于 P i t P_{it} Pit上的节点 j j j, T ˉ ( j ) = T ˉ ( j + 1 ) + d j , j + 1 \bar{T}(j)=\bar{T}(j+1)+d_{j,j+1} Tˉ(j)=Tˉ(j+1)+dj,j+1,因此 T ˉ ( b v ) = T ˉ ( i ) − ∑ k = 1 v − 1 d b k , b k + 1 \bar{T}(b_v) = \bar{T}(i) - \sum_{k=1}^{v-1}d_{b_k,b_{k+1}} Tˉ(bv)=Tˉ(i)−∑k=1v−1dbk,bk+1
-
对于 P i t P_{it} Pit上的节点 j j j, S ˉ ( j + 1 ) ≤ S ˉ ( j ) + d j , j + 1 \bar{S}(j+1) \le \bar{S}(j)+d_{j,j+1} Sˉ(j+1)≤Sˉ(j)+dj,j+1,因此 S ˉ ( b v ) ≤ S ˉ ( i ) + ∑ k = 1 v − 1 d b k , b k + 1 \bar{S}(b_v) \le \bar{S}(i)+\sum_{k=1}^{v-1}d_{b_k,b_{k+1}} Sˉ(bv)≤Sˉ(i)+∑k=1v−1dbk,bk+1
-
则 S ˉ ( i ) + T ˉ ( i ) ≥ S ˉ ( b v ) − ∑ k = 1 v − 1 d b k , b k + 1 + T ˉ ( b v ) + ∑ k = 1 v − 1 d b k , b k + 1 = S ˉ ( b v ) + T ˉ ( b v ) \bar{S}(i)+\bar{T}(i) \ge \bar{S}(b_v) - \sum_{k=1}^{v-1}d_{b_k,b_{k+1}} + \bar{T}(b_v) + \sum_{k=1}^{v-1}d_{b_k,b_{k+1}} = \bar{S}(b_v) + \bar{T}(b_v) Sˉ(i)+Tˉ(i)≥Sˉ(bv)−∑k=1v−1dbk,bk+1+Tˉ(bv)+∑k=1v−1dbk,bk+1=Sˉ(bv)+Tˉ(bv)
-
此外, S ′ ( b v ) ≤ x ′ S'(b_v) \le x' S′(bv)≤x′(case 3的条件), T ˉ ( b v ) ≤ y ′ \bar{T}(b_{v}) \le y' Tˉ(bv)≤y′(前置结论),则 S ˉ ( b v ) + T ˉ ( b v ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(b_v)+\bar{T}(b_v) \ge S'(r)+T'(r) Sˉ(bv)+Tˉ(bv)≥S′(r)+T′(r)成立**(case 1的结论)**
-
则 S ˉ ( i ) + T ˉ ( i ) ≥ S ˉ ( b v ) + T ˉ ( b v ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i) \ge \bar{S}(b_v) + \bar{T}(b_v) \ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)≥Sˉ(bv)+Tˉ(bv)≥S′(r)+T′(r)
-
结论成立
2.3.2、case B分析
case A:存在一个节点 b v b_v bv( 1 < v < w 1 < v < w 1<v<w), S ′ ( b v ) > x ′ S'(b_v) > x' S′(bv)>x′
证明:
- 基于前置结论,可知 T ′ ( b j ) > T ˉ ( b j ) > y ′ , 1 ≤ j ≤ w − 1 T'(b_j)> \bar{T}(b_j) > y',1 \le j \le w-1 T′(bj)>Tˉ(bj)>y′,1≤j≤w−1,因此 T ′ ( b v ) > y ′ T'(b_v) > y' T′(bv)>y′
- 因为 S ′ ( b v ) > x ′ S'(b_v) > x' S′(bv)>x′ 且 T ′ ( b v ) > y ′ T'(b_v) > y' T′(bv)>y′,则 S ˉ ( b v ) + T ˉ ( b v ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(b_v) + \bar{T}(b_v) \ge S'(r)+T'(r) Sˉ(bv)+Tˉ(bv)≥S′(r)+T′(r)(case 2的结论)
- 由case A的证明过程可知, S ˉ ( i ) + T ˉ ( i ) ≥ S ˉ ( b v ) + T ˉ ( b v ) \bar{S}(i)+\bar{T}(i) \ge \bar{S}(b_v) + \bar{T}(b_v) Sˉ(i)+Tˉ(i)≥Sˉ(bv)+Tˉ(bv),因此 S ˉ ( i ) + T ˉ ( i ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i) \ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)≥S′(r)+T′(r)
- 结论成立
2.3.3、case C分析
case C: S ′ ( b v ) ≤ x ′ , 1 < v < w S'(b_v) \le x',1 < v < w S′(bv)≤x′,1<v<w 且 S ′ ( b v ) > x ′ , w ≤ v ≤ l S'(b_v)> x',w \le v \le l S′(bv)>x′,w≤v≤l
说明:case C是case A与case B的补集(case A与case B以外的情形)
证明:
- 由case A的证明过程可知, S ˉ ( i ) + T ˉ ( i ) ≥ S ˉ ( b w − 1 ) + T ˉ ( b w − 1 ) \bar{S}(i)+\bar{T}(i) \ge \bar{S}(b_{w-1}) + \bar{T}(b_{w-1}) Sˉ(i)+Tˉ(i)≥Sˉ(bw−1)+Tˉ(bw−1)
- 因为 S ′ ( b v ) ≤ x ′ , 1 < v < w S'(b_v) \le x',1 < v < w S′(bv)≤x′,1<v<w,则 S ˉ ( b w − 1 ) = S ′ ( b w − 1 ) \bar{S}(b_{w-1})=S'(b_{w-1}) Sˉ(bw−1)=S′(bw−1),因此, S ˉ ( i ) + T ˉ ( i ) ≥ S ’ ( b w − 1 ) + T ˉ ( b w − 1 ) \bar{S}(i)+\bar{T}(i) \ge S’(b_{w-1}) + \bar{T}(b_{w-1}) Sˉ(i)+Tˉ(i)≥S’(bw−1)+Tˉ(bw−1)
- 因为 T ˉ ( b w − 1 ) = T ˉ ( b w ) + d b w − 1 , b w \bar{T}(b_{w-1})=\bar{T}(b_w)+d_{b_{w-1},b_w} Tˉ(bw−1)=Tˉ(bw)+dbw−1,bw,则 S ˉ ( i ) + T ˉ ( i ) ≥ S ’ ( b w − 1 ) + T ˉ ( b w − 1 ) = S ’ ( b w − 1 ) + T ˉ ( b w ) + d b w − 1 , b w \bar{S}(i)+\bar{T}(i) \ge S’(b_{w-1}) + \bar{T}(b_{w-1})=S’(b_{w-1}) + \bar{T}(b_w)+d_{b_{w-1},b_w} Sˉ(i)+Tˉ(i)≥S’(bw−1)+Tˉ(bw−1)=S’(bw−1)+Tˉ(bw)+dbw−1,bw
- 因为 T ˉ ( b w ) = T ′ ( b w ) \bar{T}(b_w)=T'(b_w) Tˉ(bw)=T′(bw)(前置结论:节点 b w b_w bw已经反向收敛),则 S ˉ ( i ) + T ˉ ( i ) ≥ S ’ ( b w − 1 ) + T ′ ( b w ) + d b w − 1 , b w \bar{S}(i)+\bar{T}(i) \ge S’(b_{w-1}) + T'(b_w)+d_{b_{w-1},b_w} Sˉ(i)+Tˉ(i)≥S’(bw−1)+T′(bw)+dbw−1,bw
- 因为 T ′ ( b w ) + d b w − 1 , b w ≥ T ′ ( b w − 1 ) T'(b_w)+d_{b_{w-1},b_w} \ge T'(b_{w-1}) T′(bw)+dbw−1,bw≥T′(bw−1)(距离更新条件),则 S ˉ ( i ) + T ˉ ( i ) ≥ S ’ ( b w − 1 ) + T ′ ( b w − 1 ) \bar{S}(i)+\bar{T}(i) \ge S’(b_{w-1}) + T'(b_{w-1}) Sˉ(i)+Tˉ(i)≥S’(bw−1)+T′(bw−1)
- 若只考虑case 3的假设,则
T
′
(
b
w
−
1
)
>
y
′
T'(b_{w-1})>y'
T′(bw−1)>y′
- 考虑到节点 b w b_w bw已经反向收敛(节点 b w b_w bw拓展的时候会更新 T ′ ( b w − 1 ) T'(b_{w-1}) T′(bw−1)),因为节点 b w b_w bw与 b w − 1 b_{w-1} bw−1都在最短路 P i t P_{it} Pit上,则此时的 T ′ ( b w − 1 ) = T ˉ ( b w − 1 ) T'(b_{w-1})=\bar{T}(b_{w-1}) T′(bw−1)=Tˉ(bw−1)
- 因此,节点 b w − 1 b_{w-1} bw−1已经反向收敛
- 根据case C的假设, S ′ ( b w − 1 ) ≤ x ′ S'(b_{w-1}) \le x' S′(bw−1)≤x′,则 S ˉ ( i ) + T ˉ ( i ) ≥ S ’ ( b w − 1 ) + T ′ ( b w − 1 ) = S ˉ ( b w − 1 ) + T ˉ ( b w − 1 ) ≥ S ′ ( r ) + T ′ ( r ) \bar{S}(i)+\bar{T}(i) \ge S’(b_{w-1}) + T'(b_{w-1})=\bar{S}(b_{w-1})+\bar{T}(b_{w-1}) \ge S'(r)+T'(r) Sˉ(i)+Tˉ(i)≥S’(bw−1)+T′(bw−1)=Sˉ(bw−1)+Tˉ(bw−1)≥S′(r)+T′(r)
- 结论成立
2.3.4、总结及讨论
总结(来源于DeepSeek
,虽然不是很明白,但感觉很有道理 -_- )
通过路径分解和节点 b w b_w bw、 b v b_v bv的特性分析,Case 3的证明表明
- 未收敛段的路径长度受限于算法终止时的队列最小值( x ′ + y ′ x'+y′ x′+y′)
- 收敛段的路径长度已包含在候选最短路径的比较中。
- 因此,即使反向搜索继续优化,总路径长度 S ˉ ( i ) + T ˉ ( i ) \bar{S}(i)+\bar{T}(i) Sˉ(i)+Tˉ(i)也不会低于 S ′ ( r ) + T ′ ( r ) S'(r)+T'(r) S′(r)+T′(r)
遗留问题(case 3 前置结论部分)
- 前置结论:一定存在一个节点 b w b_w bw,使 T ˉ ( b j ) > y ′ , 1 ≤ j ≤ w − 1 \bar{T}(b_j)> y',1 \le j \le w-1 Tˉ(bj)>y′,1≤j≤w−1 且 T ˉ ( b j ) ≤ y ′ , w ≤ j ≤ l \bar{T}(b_j)\le y',w \le j \le l Tˉ(bj)≤y′,w≤j≤l
- 论文中说可以根据前置结论得到
T
′
(
b
j
)
>
y
′
,
1
≤
j
≤
w
−
1
T'(b_j)> y',1 \le j \le w-1
T′(bj)>y′,1≤j≤w−1 且
T
′
(
b
j
)
≤
y
′
,
w
≤
j
≤
l
T'(b_j)\le y',w \le j \le l
T′(bj)≤y′,w≤j≤l
- 因为 T ′ ( b j ) ≥ T ˉ ( b j ) T'(b_j)\ge \bar{T}(b_j) T′(bj)≥Tˉ(bj) ,所以易得 T ′ ( b j ) > y ′ , 1 ≤ j ≤ w − 1 T'(b_j)> y',1 \le j \le w-1 T′(bj)>y′,1≤j≤w−1
- 对于 T ′ ( b j ) ≤ y ′ , w ≤ j ≤ l T'(b_j)\le y',w \le j \le l T′(bj)≤y′,w≤j≤l,需要证明(论文中并未使用到该结论,正确性存疑!!!)
三、示例代码
import heapq
def bidirectional_dijkstra(adj, start, end):
# 起点到其他节点的距离
forward_dist = {node: float('inf') for node in range(len(adj))}
# 起点距离设置为0,放入“优先队列”
forward_dist[start] = 0
forward_heap = [(0, start)]
# 各节点的上游节点
forward_prev = {}
reverse_dist = {node: float('inf') for node in range(len(adj))}
reverse_dist[end] = 0
reverse_heap = [(0, end)]
reverse_prev = {}
# 已搜索的节点
visited_forward = set()
visited_reverse = set()
# 相遇节点及起终点间的最短距离
meeting_node = None
shortest_distance = float('inf')
while forward_heap and reverse_heap:
# 选择正向或反向队列中距离更小的节点进行扩展
# heapq模块实现优先队列
forward_min = forward_heap[0][0]
reverse_min = reverse_heap[0][0]
if forward_min <= reverse_min:
# 正向扩展
current_dist, u = heapq.heappop(forward_heap)
visited_forward.add(u)
# 更新邻接节点
for i in range(len(adj)):
if adj[u][i] > 0:
visited_forward.add(i)
if forward_dist[i] > forward_dist[u] + adj[u][i]:
forward_dist[i] = forward_dist[u] + adj[u][i]
heapq.heappush(forward_heap, (forward_dist[i], i))
forward_prev[i] = u
# 若相遇,计算完整路径的长度
if i in visited_reverse:
total = forward_dist[i] + reverse_dist[i]
# 更新最短路的长度
if total < shortest_distance:
shortest_distance = total
meeting_node = i
else:
# 反向扩展
current_dist, u = heapq.heappop(reverse_heap)
visited_reverse.add(u)
for j in range(len(adj)):
if adj[j][u] > 0:
visited_reverse.add(j)
if reverse_dist[j] > reverse_dist[u] + adj[j][u]:
reverse_dist[j] = reverse_dist[u] + adj[j][u]
heapq.heappush(reverse_heap, (reverse_dist[j], j))
reverse_prev[j] = u
if j in visited_forward:
total = forward_dist[j] + reverse_dist[j]
if total < shortest_distance:
shortest_distance = total
meeting_node = j
# 终止条件:两队列最小键值之和 >= 当前最短路径
if forward_heap and reverse_heap:
current_forward_min = forward_heap[0][0]
current_reverse_min = reverse_heap[0][0]
if current_forward_min + current_reverse_min >= shortest_distance:
break
# 路径回溯:正向、反向
if meeting_node is None:
return None, float('inf')
path = []
node = meeting_node
while node != start:
path.append(node)
node = forward_prev.get(node)
path.append(start)
path = path[::-1]
node = meeting_node
while node != end:
node = reverse_prev.get(node)
path.append(node)
return path, shortest_distance
if __name__ == '__main__':
# 论文中示例图的邻接矩阵
adj = [[0, 3, 6, 7, 0, 0, 0, 0, 0],
[3, 0, 1, 0, 4, 0, 0, 0, 0],
[6, 1, 0, 0, 0, 2, 0, 0, 0],
[7, 0, 0, 0, 0, 3, 4, 0, 0],
[0, 4, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 2, 3, 0, 0, 0, 1, 2],
[0, 0, 0, 4, 0, 0, 0, 0, 5],
[0, 0, 0, 0, 1, 1, 0, 0, 2],
[0, 0, 0, 0, 0, 2, 5, 2, 0]]
path, distance = bidirectional_dijkstra(adj, 0, 8)
print(f"最短路径: {path}")
print(f"最短距离: {distance}")
四、相关链接
- 论文:https://sci-hub.se/10.1093/comjnl/9.3.275
- Dijkstra算法:https://blog.csdn.net/weixin_42639395/article/details/135485731?fromshare=blogdetail&sharetype=blogdetail&sharerId=135485731&sharerefer=PC&sharesource=weixin_42639395&sharefrom=from_link
- 双向Dijkstra算法:
- https://blog.csdn.net/woniu317/article/details/20901341?fromshare=blogdetail&sharetype=blogdetail&sharerId=20901341&sharerefer=PC&sharesource=weixin_42639395&sharefrom=from_link
- https://blog.csdn.net/weixin_43571647/article/details/134386015?fromshare=blogdetail&sharetype=blogdetail&sharerId=134386015&sharerefer=PC&sharesource=weixin_42639395&sharefrom=from_link