符号说明
- VVV:结点;
- EEE:边集;
- G=(V,E)G=(V,E)G=(V,E):带权重的有向图;
- WWW:邻接矩阵;
- δ(u,v)\delta(u,v)δ(u,v):结点uuu到结点vvv的最短距离。
邻接矩阵
邻接矩阵WWW是一个n×nn\times nn×n的矩阵,W=wijW=w_{ij}W=wij
wij={0i=j有向边(i,j)的权重i≠j且(i,j)∈E∞i≠j且(i,j)∉E
w_{ij}=
\begin{cases}
0 & i=j\\
有向边(i,j)的权重 & i\neq j 且(i,j)\in E\\
\infty & i\neq j 且(i,j)\notin E\\
\end{cases}
wij=⎩⎪⎨⎪⎧0有向边(i,j)的权重∞i=ji=j且(i,j)∈Ei=j且(i,j)∈/E
最短路径和矩阵乘法
所有结点对最短路径问题的递归解
设lij(m)l^{(m)}_{ij}lij(m)为从结点iii到结点jjj的至多包含mmm条边的任意路径的最小权重。当m=0m=0m=0时,有:
lij(m)={0i=j∞i≠j
l^{(m)}_{ij}=
\begin{cases}
0 & i=j\\
\infty & i\neq j\\
\end{cases}
lij(m)={0∞i=ji=j
对于m≥1m\ge 1m≥1,我们有:
lij(m)=min(lij(m−1),min1≤k≤n(lik(m−1)+wkj))=min1≤k≤n(lik(m−1)+wkj)l^{(m)}_{ij}=\min(l^{(m-1)}_{ij},\min\limits_{1\leq k\leq n} (l^{(m-1)}_{ik}+w_{kj}))=\min\limits_{1\leq k\leq n} (l^{(m-1)}_{ik}+w_{kj})lij(m)=min(lij(m−1),1≤k≤nmin(lik(m−1)+wkj))=1≤k≤nmin(lik(m−1)+wkj)
(因为w(j,j)=0w(j,j)=0w(j,j)=0,所以后面的等式成立)
由于我们假设图中不包含负权环,所以结点iii到结点jjj的最短路径至多包含n−1n-1n−1条边,所以我们有:
δ(i,j)=lij(n−1)=lij(n)=lij(n+1)=⋯\delta(i,j)=l^{(n-1)}_{ij}=l^{(n)}_{ij}=l^{(n+1)}_{ij}=\cdotsδ(i,j)=lij(n−1)=lij(n)=lij(n+1)=⋯
自底向上计算最短路径权重
根据邻接矩阵WWW,我们可以计算出矩阵序列L(1),L(2),⋯ ,L(n−1)L^{(1)},L^{(2)},\cdots,L^{(n-1)}L(1),L(2),⋯,L(n−1)。特别地,L(1)=WL^{(1)}=WL(1)=W。
下面的伪代码展示了如何根据WWW和L(m−1)L^{(m-1)}L(m−1)计算L(m)L^{(m)}L(m):
EXTEND-SHORTEST-PATHS(L,W)
n = L.rows
let L' be a new n*n matrix
for i = 1 to n
for j = 1 to n
L'[i][j]=∞
for k = 1 to n
L'[i][j] = min(L'[i][j], L[i][k]+w(k,j))
return L'
由于上述算法有3层嵌套for循环,所以时间复杂度为O(n3)O(n^3)O(n3)。
可以看出,EXTEND-SHORTEST-PATHS算法和矩阵乘法在形式上是非常相似的。
下面的算法给出了如何在O(n4)O(n^4)O(n4)的时间内计算所有节点对的最短路径:
SLOW-ALL-PAIRS-SHORTEST-PATHS(W)
n = W.rows
L(1) = W
for m = 2 to n-1
let L(m) be a new n*n matrix
L(m) = EXTEND-SHORTEST-PATHS(L(m-1),W)
return L(n-1)
改进算法的运行时间
我们知道:∀m>n−1⟹L(m)=L(n−1)\forall m>n-1\Longrightarrow L^{(m)}=L^{(n-1)}∀m>n−1⟹L(m)=L(n−1)。所以我们在求解所有结点对的最短路径时,未必一定要计算出L(n−1)L^{(n-1)}L(n−1)。
下面的算法采用重复平方技术,使算法的时间复杂度降至O(n3logn)O(n^3\log n)O(n3logn):
FASETER-ALL-PAIRS-SHORTEST-PATHS(W)
n = W.rows
L(1) = W
m = 1
while m < n-1
let L(2*m) be a new n*n matrix
L(2*m) = EXTEND-SHORTEST-PATHS(L(m),L(m))
m = 2*m
return L(m)
Floyd-Warshall算法
最短路径的结构
Floyd-Warshall算法主要关注最短路径上的中间结点。
假定图GGG中的所有结点为{1,2,⋯ ,n}\{1,2,\cdots,n\}{1,2,⋯,n},考虑其中的一个子集{1,2,⋯ ,k}\{1,2,\cdots,k\}{1,2,⋯,k},对于任意的结点对i,j∈Vi,j\in Vi,j∈V,设ppp为所有中间结点均取自集合{1,2,⋯ ,k}\{1,2,\cdots,k\}{1,2,⋯,k}的路径中的最短路。对于路径ppp,我们讨论以下两种情况:
- kkk不在路径ppp上:p也是中间结点均取自集合{1,2,⋯ ,k−1}\{1,2,\cdots,k-1\}{1,2,⋯,k−1}的路径中的最短路。
- kkk在路径ppp上:将p拆分为:i⇝p1k⇝p2ji\leadsto^{p_1}k\leadsto^{p_2}ji⇝p1k⇝p2j,p1p_1p1为结点iii到kkk的、所有中间结点取自集合{1,2,⋯ ,k−1}\{1,2,\cdots,k-1\}{1,2,⋯,k−1}的最短路径,p2p_2p2同理。
所有结点对最短路径问题的递归解
设dij(k)d^{(k)}_{ij}dij(k)为从结点iii到结点jjj的、所有中间结点均取自集合{1,2,⋯ ,k}\{1,2,\cdots,k\}{1,2,⋯,k}的最短路径权值。dij(0)d^{(0)}_{ij}dij(0)表示i,ji,ji,j的路径上没有任何中间结点,所以有:dij(0)=wijd^{(0)}_{ij}=w_{ij}dij(0)=wij。递归定义dij(k)d^{(k)}_{ij}dij(k)如下:
dij(k)={wi,jk=0min(dij(k−1),dik(k−1)+dkj(k−1))k>0
d^{(k)}_{ij}=
\begin{cases}
w_{i,j} & k=0\\
\min(d^{(k-1)}_{ij},d^{(k-1)}_{ik}+d^{(k-1)}_{kj}) & k>0\\
\end{cases}
dij(k)={wi,jmin(dij(k−1),dik(k−1)+dkj(k−1))k=0k>0
因为对于图GGG中的任何路径来说,所有中间结点均取自集合{1,2,⋯ ,n}\{1,2,\cdots,n\}{1,2,⋯,n},所以dij(n)=δ(i,j)d^{(n)}_{ij}=\delta(i,j)dij(n)=δ(i,j)。
自底向上计算最短路径权重
FLOYD-WARSHALL(W)
n = w.rows
D(0) = W
for k = 1 to n
let D(k) be a new n*n matrix
for i = 1 to n
for j = 1 to n
d(k)[i][j] = min(d(k-1)[i][j], d(k-1)[i][k]+d(k-1)[k][j])
return D(n)
时间复杂度为O(n3)O(n^3)O(n3)。
构建一条最短路径
我们在求解矩阵序列D(0),D(1),⋯ ,D(n)D^{(0)},D^{(1)},\cdots,D^{(n)}D(0),D(1),⋯,D(n)的同时求解矩阵序列Π(0),Π(1),⋯ ,Π(n)\Pi^{(0)},\Pi^{(1)},\cdots,\Pi^{(n)}Π(0),Π(1),⋯,Π(n)。
对Π(0)\Pi^{(0)}Π(0)有:
πij(0)={i,i≠j且w(i,j)≠∞NIL,i=j或w(i,j)=∞
\pi^{(0)}_{ij}=
\begin{cases}
i, & i\ne j且w(i,j)\ne \infty\\
NIL,& i=j或w(i,j)=\infty\\
\end{cases}
πij(0)={i,NIL,i=j且w(i,j)=∞i=j或w(i,j)=∞
对Π(k)(k≥1)\Pi^{(k)}(k\ge 1)Π(k)(k≥1)有:
πij(k)={πij(k−1),dij(k−1)≤dik(k−1)+dkj(k−1)πkj(k−1),dij(k−1)>dik(k−1)+dkj(k−1)
\pi^{(k)}_{ij}=
\begin{cases}
\pi^{(k-1)}_{ij}, & d^{(k-1)}_{ij}\leq d^{(k-1)}_{ik}+d^{(k-1)}_{kj}\\
\pi^{(k-1)}_{kj},& d^{(k-1)}_{ij}> d^{(k-1)}_{ik}+d^{(k-1)}_{kj}\\
\end{cases}
πij(k)={πij(k−1),πkj(k−1),dij(k−1)≤dik(k−1)+dkj(k−1)dij(k−1)>dik(k−1)+dkj(k−1)
有向图的传递闭包
给定有向图G=(V,E)G=(V,E)G=(V,E),定义图GGG的传递闭包为G∗=(V,E∗)G^*=(V,E^*)G∗=(V,E∗),其中E∗={(i,j)E^*=\{(i,j)E∗={(i,j):如果图G中包含一条从i到j的路径}\}}。
我们对Floyd-Warshall算法进行一点改进,用以更好地求解有向图的传递闭包。
定义:若图中存在一条从iii到jjj的、所有中间结点均取自集合{1,2,⋯ ,k}\{1,2,\cdots,k\}{1,2,⋯,k}的路径,则tij(k)=1t^{(k)}_{ij}=1tij(k)=1,否则tij(k)=0t^{(k)}_{ij}=0tij(k)=0。
根据定义我们容易得到:
tij(0)={1,i=j或w(i,j)≠∞0,i≠j且w(i,j)=∞
t^{(0)}_{ij}=
\begin{cases}
1, & i=j或w(i,j)\ne \infty\\
0,& i\ne j且w(i,j)=\infty\\
\end{cases}
tij(0)={1,0,i=j或w(i,j)=∞i=j且w(i,j)=∞
当k≥1k\ge 1k≥1时,有:
tij(k)=tij(k−1)∨(tik(k−1)∧tkj(k−1))
t^{(k)}_{ij}=t^{(k-1)}_{ij}\lor (t^{(k-1)}_{ik}\land t^{(k-1)}_{kj})
tij(k)=tij(k−1)∨(tik(k−1)∧tkj(k−1))
Johnson算法
使用斐波那契堆实现最小优先队列时,Johnson算法的时间复杂度为O(V2logV+VE)O(V^2\log V+VE)O(V2logV+VE)。使用二叉堆实现最小优先队列时,时间复杂度为O(VElogV)O(VE\log V)O(VElogV)在算法的执行过程中需要使用Dijkstra和Bellman-Ford算法。
Johnson算法使用了重赋权重技术。具体如下:
- 如果图中均为非负权值的边,则对每个结点执行Dijkstra算法,从而找到所有结点对的最短路径。
- 如果图中包含负权边,但不包含负权环,则需要计算出一组新的权重,然后再对每个结点调用Dijkstra算法。
新的权重w^\hat{w}w^必须满足如下性质:
- 对任意结点对u,vu,vu,v,如果在原权重www下,存在一条最短路径ppp当且仅当在新权重下w^\hat{w}w^下,ppp仍然为两结点间的最短路径。
- 对于所有的边(u,v)(u,v)(u,v),新权重w^(u,v)\hat{w}(u,v)w^(u,v)为非负值。
重赋权重来维持最短路径
令w^(u,v)=w(u,v)+h(u)−h(v)\hat{w}(u,v)=w(u,v)+h(u)-h(v)w^(u,v)=w(u,v)+h(u)−h(v),我们假设在新权重w^\hat{w}w^下的最短路径权重为δ^\hat{\delta}δ^。
首先证明,对v0,vkv_0,v_kv0,vk的最短路p=⟨v0,v1,⋯ ,vk⟩p=\langle v_0,v_1,\cdots,v_k\ranglep=⟨v0,v1,⋯,vk⟩,w(p)=δ(u,v)w(p)=\delta(u,v)w(p)=δ(u,v)当且仅当w^(p)=δ^(u,v)\hat{w}(p)=\hat{\delta}(u,v)w^(p)=δ^(u,v)。对任意路径,我们有:
w^(p)=∑i=1kw^(vi−1,vi)=∑i=1k(w(vi−1,vi)+h(vi−1)−h(vi))=∑i=1kw(vi−1,vi)+h(v0)−h(vk)=w(p)+h(v0)−h(vk)\hat{w}(p)=\sum\limits^{k}_{i=1}\hat{w}(v_{i-1},v_i)\\=\sum\limits^{k}_{i=1}(w(v_{i-1},v_i)+h(v_{i-1})-h(v_i))\\=\sum\limits^{k}_{i=1}{w}(v_{i-1},v_i)+h(v_0)-h(v_k)\\=w(p)+h(v_0)-h(v_k)w^(p)=i=1∑kw^(vi−1,vi)=i=1∑k(w(vi−1,vi)+h(vi−1)−h(vi))=i=1∑kw(vi−1,vi)+h(v0)−h(vk)=w(p)+h(v0)−h(vk)
由于h(v0),h(vk)h(v_0),h(v_k)h(v0),h(vk)不依赖于任何具体路径,所以新权重下的路径之间的大小关系保持不变,由此证明了:w(p)=δ(u,v)w(p)=\delta(u,v)w(p)=δ(u,v)当且仅当w^(p)=δ^(u,v)\hat{w}(p)=\hat{\delta}(u,v)w^(p)=δ^(u,v)。
然后证明,若原权重www下存在负权环,则新权重w^\hat{w}w^下仍然存在负权环。考虑任意环路c=⟨v0,v1,⋯ ,vk⟩,v0=vkc=\langle v_0,v_1,\cdots,v_k\rangle,v_0=v_kc=⟨v0,v1,⋯,vk⟩,v0=vk,我们有w^(c)=w(c)+h(v0)−h(vk)=w(c)\hat{w}(c)=w(c)+h(v_0)-h(v_k)=w(c)w^(c)=w(c)+h(v0)−h(vk)=w(c)。命题得证。
通过重赋权值来生成非负权重
我们制作一幅新图G′=(V′,E′)G'=(V',E')G′=(V′,E′),其中V′=V∪{s},E′=E′∪{(s,v):v∈V},w(s,v)=0V'=V\cup\{s\},E'=E'\cup \{ (s,v):v\in V\},w(s,v)=0V′=V∪{s},E′=E′∪{(s,v):v∈V},w(s,v)=0。
我们定义:对所有结点v∈V′v\in V'v∈V′,h(v)=δ(s,v)h(v)=\delta(s,v)h(v)=δ(s,v)。根据三角不等式我们知道:δ(s,v)≤δ(s,u)+w(w,v)\delta(s,v)\leq\delta(s,u)+w(w,v)δ(s,v)≤δ(s,u)+w(w,v),变形得:δ(s,u)−δ(s,v)≥w(w,v)\delta(s,u)-\delta(s,v)\geq w(w,v)δ(s,u)−δ(s,v)≥w(w,v),即h(u)−h(v)≥w(u,v)h(u)-h(v)\ge w(u,v)h(u)−h(v)≥w(u,v),从而有w^(u,v)=w(u,v)+h(u)−h(v)≥0\hat{w}(u,v)=w(u,v)+h(u)-h(v)\ge 0w^(u,v)=w(u,v)+h(u)−h(v)≥0。
本文深入探讨了图的最短路径算法,包括邻接矩阵、Dijkstra、Floyd-Warshall和Johnson算法。详细解释了如何计算最短路径权重,以及如何构建最短路径,并介绍了有向图的传递闭包计算。同时,提到了如何通过重赋权重处理含有负权边的图。

1682

被折叠的 条评论
为什么被折叠?



