[算法分析与设计] 1. 全源最短路近似

全源最短路 (APSP) 近似。有两种近似

  • stretch k. δ(u,v)d(u,v)kδ(u,v).
  • surplus t. δ(u,v)d(u,v)δ(u,v)+t.

其中,δ(u,v) 表示 u,v 间真实的最短路长度。

为什么我们只考虑 δ(u,v)d(u,v) 呢,因为在组合算法中,“近似”都指用更少的信息去做松弛,因此每一个近似的值都对应着一条真实的路径。而在包含了 (min,+) 矩阵乘近似等代数算法中,向上近似和向下近似都是可以的((min,+) 矩阵乘近似的一个做法是,降低分辨率,用取整后的值做决策以降低复杂度),这时近似的值不对应一条真实的最短路了,只是说,这样的代数算法也一定包含了组合的部分,向上近似是为了和算法的其他部分不等号方向一致。

先来考虑无权图上的 surplus 2 近似。2 代表着我们可以选择最短路上的某个邻居作为松弛点。一个朴素的想法是,用度数的大小进行“根号分治”,只将一小部分点作为松弛点。

考虑将图上一些点设为关键点,使得所有度数大的点与至少一个关键点相连,用这些关键点松弛这些度数大的点,而将度数大的点之间的边删去。

令图上每个点有 1k 的概率被选为关键点,点之间概率独立,则度数为 d 的点有 1(11k)d 的概率与一个关键点相邻。当 k=dclogn 时,1(11k)d11nc,因此

定理 1 给定度数 d,可以找到一个大小为 O~(nd) 的集合 D,使得高概率所有度数 d 的点都与至少一个 D 中的点相邻。

其中 O~ 表示 O 忽略 log

于是我们可以对度数大的点用关键点松弛,度数小的点直接 BFS。

算法 1 (无权图上的 surplus 2 近似 I [Aingworth-Chekuri-Indyk-Motwani '96])

对图 (V,E),令

  • V1 是度数 d 的所有点。

  • D1 是一个大小为 O~(nd) 的关键点集,使得每一个 V1 中的点都与至少一个 D1 中的点相邻。

  • E1uV1vV1 的所有边 (u,v)|E2|nd

uD1,vV,用 BFS 计算出所有 δ(u,v)。时间复杂度 O(m|D1|)=O~(nmd)。令 δ(D1×V) 表示边集 {(u,v,δ(u,v))}

(V,E1δ(D1×V)) 跑 Dijkstra。时间复杂度 O(n(|E1|+n|D1|))=O(n2d)

考虑将 Dijkstra 的结果作为答案。

  • uD1vD1d(u,v)=δ(u,v)
  • u,v 最短路不经过任何 V1 中的点,d(u,v)=δ(u,v)
  • 否则若经过了某个 wV1,其相邻的关键点 wD1,则 d(u,v)δ(u,w)+δ(w,v)δ(u,w)+δ(w,v)+2=δ(u,v)+2

因此这是一个 surplus 2 近似。

时间复杂度为 O~(n2d+nmd),令 d=n12m12,最终时间复杂度为 O~(n32m12),一般图 m=O(n2) 时为 O~(n52)

在第三种情况中,由于此时并不知道关键点是否就在最短路上,精确的长度无法求出。

这个算法是可以被优化的。考虑最短路上 w 的一个相邻的关键点 wuwwwv 也是一个合法的 surplus 2 近似。因此算法 1 的浪费之处在于用 BFS 求出了所有的 δ(D1×V)。我们并不需要 D1V 的一般意义上的最短路,而可以强制所有的近似都采取这样的策略,那就只需要对最短路上的边和 ww 的边跑 BFS 即可。但问题在于我们无法提前知道要保留的边是哪些。

一个折中的策略是对度数大小选取两个阈值,较大的阈值对应的关键点个数少,按照同算法 1 的方法处理。在考虑一条最短路时,先看其能否通过这些关键点松弛,如果不行再考虑较小的阈值对应的关键点,这样后者就不需要再在整个图上跑 BFS 了,因为此时最短路有了性质,只需要保留满足这个性质的边(即不经过大度数的点的那些边)。

算法 2 (无权图上的 surplus 2 近似 II [Dor-Halperin-Zwick '96])

对图 (V,E),令

  • d1d2.

  • V1 是度数 d1 的所有点。

  • D1 是一个大小为 O~(nd1) 的关键点集,使得每一个 V1 中的点都与至少一个 D1 中的点相邻。

  • V2 是度数 d2 的所有点。

  • D2 是一个大小为 O~(nd2) 的关键点集,使得每一个 V2 中的点都与至少一个 D2 中的点相邻。

  • E1uV1vV1 的所有边 (u,v)|E1|nd1

  • E2uV2vV2 的所有边 (u,v)|E2|nd2

  • E 是每个 V2 中的点和任一 D2 中的点连接的边集。|E|=O~(n)

用 BFS 计算 δ(D2×V)。时间复杂度 O(m|D2|)=O~(n3d2)

用 BFS 在生成子图 (V,E2) 上计算 δ(D1×V)。时间复杂度 O(|E2||D1|)=O~(n2d2d1)

uV,在 (V,E1δ(D2×V)δ({u}×D1)E) 上跑 Dijkstra。时间复杂度 O~(n(nd1+n2d2+nd1+n))=O~(n2d1+n3d2)

考虑将 Dijkstra 的结果作为答案。

  • uD2vD2d(u,v)=δ(u,v)
  • u,v 最短路不经过任何 V1 中的点,也即,最短路上的点度数都很小,d(u,v)=δ(u,v)
  • 否则,若最短路经过了某个 wV2(也即,最短路上有一个度数很大的点),其相邻的关键点 wD2,则 d(u,v)δ(u,w)+δ(w,v)δ(u,w)+δ(w,v)+2=δ(u,v)+2
  • 否则,若最短路不经过任何 V2 中的点,但是经过了某个 wV1(也即,所有点的度数都不大,但是存在度数中等的点),其相邻的关键点 wD1。令 w 是最短路上最后一个这样的点,w 是那个 (w,w)E 的关键点。此时 uw 不经过任何 V2 中的点,因此所有边 E2(w,w),(w,w)Ewv(除了 w,v 自己)不经过任何 V1 中的点,因此所有边 E1。所以 uwwwv 是一条被包含的路径,d(u,v)δ(u,v)+2

因此这是一个 surplus 2 近似。

时间复杂度为 O~(n2d2d1+n2d1+n3d2)=O~(n2(d1+d2d1+nd2))。后三者乘积为 n,令 d1=n13,d2=n23,最终时间复杂度为 O~(n73)

我们也可以把算法 2 看作仅考虑一个阈值 d2,将 G=(V,E2) 直接应用算法 1,这样的总复杂度为 O~(n3d2+n32(nd2)12),令 d2=n23,也可以得到 O~(n73) 的结果。

注意在 Dijkstra 时,我们对每个 u 包含了 δ({u}×D1)。在第四种情况中,只有当我们选了最后一个这样的 w,以及在 Dijkstra 中包含了 E1,才可以让仅包含来自起点的 δ({u}×D1),否则来自终点的 δ({v}×D1) 也需要包含进去。两者的复杂度是有天差地别的。如果只包含一侧,便可以用单源最短路径每次只加 O(nd1) 条边,如果包含两侧,就只能把所有边 δ(D1×V) 同时都加进去,这样将失去任何复杂度优势。

这个算法使用了两个阈值,将度数分为三层。立刻产生的想法便是可不可以通过分更多层来得到更优秀的复杂度,比如分 k 层就能得到诸如 O(poly(k)n2+1k) 的算法。答案是否定的。因为在最短路所有点不经过 Vi 但经过了 Vi1 时,如果我们选取最后一个 Vi1 中的点,那么 wv 的所有边 Ei1,因此 Dijkstra 中要加入 Ei1,但是这样最终复杂度就会有一项 O~(n2dk2)。因此这个做法下分更多层没有意义。

换句话说,这个算法的优化点就在于,考虑 δ(u,w)+δ(w,v) 时,起点侧 δ(u,w) 只需要加很少的边。

但是,与组合算法不同的是,还有另一类算法,直接专注于优化 minw{δ(u,w)+δ(w,v)} 这个计算过程本身。前面我们把所有需要的边并在一起算 Dijkstra 是为了方便,现在我们来仔细考量一下不同的边之间的需求关系。

对于四种情况

  • uD2vD2,通过 δ(D2×V) 得到。
  • 最短路不经过 V1 中的点,通过 (V,E1) 上的 Dijkstra 得到。
  • 最短路经过了某个 wV2,通过 minwD2{δ(u,w)+δ(w,v)} 得到。
  • 最短路不经过 V2 中的点,但是经过了某个 wV1,通过 minwD1{δ(u,w)+1+δ(V,E1)(w,v)} 得到。

也就是说,在 Dijkstra 中,最短路实际上只有两步。

δ(V×D2) 视作矩阵,则我们需要求出 δ(V×D2)δ(D2×V),其中 表示 (min,+) 矩阵乘法。对一般的 (min,+) 矩阵乘,没有 O(n3Ω(1)) 的做法。

不过,我们可以针对问题的特殊性质研究特殊的矩阵乘法。如果我们将节点序列按照图的任意一棵生成树的欧拉序排列(此时一个点会出现多次),则 δ(D1×V) 的上下相邻两个元素的差不超过 1,对于拥有这样特殊性质的 (min,+) 矩阵乘(其中一个矩阵为 Row/Column Bounded-difference),有 O~(n(2+r+ω(r))/2) 的做法,其中 ω(r) 表示 n×nr 矩阵和 nr×n 矩阵做正常矩阵乘法的指数 [Chi-Duan-Xie-Zhang '22]。

由于我们现在只做 (min,+),第四种情况不能直接处理。因此我们进行分层,将每一层之间的 gap 缩小,做 logn(min,+)

算法 3 (无权图上的 surplus 2 近似 III [Deng-Kirkpatrick-Rong-V. Williams-Zhong '22])

对图 (V,E),令

  • d0d1dk=nk 待定。

  • Vi 是度数 di 的所有点。

  • Di 是一个大小为 O~(ndi) 的关键点集,使得每一个 Vi 中的点都与至少一个 Di 中的点相邻。

  • EiuVivVi 的所有边 (u,v)|Ei|ndi

  • E 是每个 Vi 中的点和任一 Di 中的点连接的边集。|E|=O~(n)

用 BFS 在 (V,EiE) 上计算 δi(Di1×V)1ik,时间复杂度为 O~(n2didi1)

(V,E0) 应用算法 1 得到 d(u,v)。时间复杂度 O(n2d012)

求出 minwDi1ik{δi(u,w)+δi(w,v)},假设 d 的选取足够分散,使得 k=o(nε),则复杂度为

O~(n(2+(1lognd0)+ω(1lognd0))/2)

考虑将 d(u,v)=min(d(u,v),minwDi1ik{δi(u,w)+δi(w,v)}) 作为答案。

使用类似上文的推导可知这是一个 surplus 2 近似。

时间复杂度为

O~(n2d012+n2(d1d0+d2d1++dk1dk2+ndk1)+n(3lognd0+ω(1lognd0))/2)

可知 didi1 都相等,令他们均为 2,则 k=O(logn),符合要求。剩下的便是解方程,令 d0=n1r,则方程为 5212r=(2+r+ω(r))/2,即 2r+ω(r)=3ω(r) 是一个很复杂的函数,查表可以估计出 r0.427,最终复杂度 O~(n2.2867)

如果不使用快速矩阵乘,直接用朴素的 O~(n3lognd0) 来做,最终复杂度与算法 2 相同。

最后,一个额外的事情是,我们可以将上面几个算法去随机化。上述算法均基于定理 1,考虑用别的方法替换掉它。考虑对一个点 v,如果将其作为关键点,则 vv 的邻居都被覆盖了。我们总是从没有被覆盖的点中再考虑一个作为关键点,也即每次将 vv 的邻居删去,考虑剩下的图。如果限制从度数大的开始删,那么当删去了 B 个点,剩下的图所有点中最大的度数为 d,则 Bdn,dnB,因此剩下的图的边数只有 O(n2B) 条。这是符合我们的要求的,因为上述几个算法对关键点的要求均为:关键点的数量是 O(nd) 时,剩余的边的数量是 O(nd)。所以上面几个算法均可以是确定性的,O~ 也均可以改为 O


对于有向图,由于上述算法均有 www 的情节,它们无法再适用。

对于有权图,相邻并不意味着距离相近,因此 surplus 并不合理。现在尝试考虑 stretch。

先来考虑怎么寻找一个点 s 的前 b 相近的点,即最短路长度最近的 b 个点。如果直接使用 Dijkstra,复杂度是 O~(nb) 的,不过我们可以限制 Dijkstra 的运行轮数与队列长度做到 O~(b2)

对 stretch 近似,一个最朴素的想法是这样的:我们还是沿用寻找关键点 w,用 d(u,v)=δ(u,w)+δ(w,v) 来近似 δ(u,v) 的方法。此时若有 δ(u,w)δ(u,v),则 δ(w,v)δ(w,u)+δ(u,v)2δ(u,v),d(u,v)=δ(u,w)+δ(w,v)3δ(u,v),因此得到一个很粗糙的上界 stretch 3

算法 4 (带权图上的 stretch 3 近似)

对图 (V,E),令

  • ball(v) 表示离 v 最近的 b 个点。对每个 v 寻找 ball(v) 的时间复杂度为 O(nb2)

  • D 是大小为 O~(nb) 的关键点集,使得每个 ball(v)D

对每个 D 跑完整的 Dijkstra,得到 δ(D×V)

对于 uDvDvball(u)d(u,v)=δ(u,v)

否则,考虑 wball(u)Dd(u,v)=δ(u,w)+δ(w,v)

这是一个 stretch 3 近似。

时间复杂度为 O~(nb2+n3b),令 b=n23,最终时间复杂度为 O~(n73)

这是一个广为人知 (folklore) 的算法。更优秀地,stretch 2O~(n32m12) 的做法,stretch 73O~(n73) 的做法,stretch 3O~(n2) 的做法。[Cohen-Zwick '97]

如果考虑空间复杂度的优化,我们所做的便是把规模 n×n 的最短路表 δ(V×V) 化简为一个空间更小的数据结构,使其能快速查询两点间的(近似)最短路。在上面的算法中为 O(n53) 空间  O(1) 查询,如果不考虑时间复杂度的最优,令 b=n12,能做到 O(n32)O(1)。对 stretch 2k1O(kn1+1k)O(k) 的做法 [Thorup, Zwick '01]。

如果我们在无权图上做 stretch,我们可以非常轻松地给出一个 O~(n2)(2,1) 近似,其中 (a,b) 近似表示 d(u,v)aδ(u,v)+b。优化点在于我们不用像算法 3 那样计算出 minwDi1ik{δi(u,w)+δi(w,v)},而实际上只需要用那个离 u 最近的关键点和那个离 v 最近的关键点作为松弛点,因为两者中恰好有一个没有一半的最短路长度。

算法 5 (无权图上的 (2,1) 近似)

对图 (V,E),令

  • di=2i0ilogn

  • Vi 是度数 di 的所有点。

  • Di 是一个大小为 O~(ndi) 的关键点集,使得每一个 Vi 中的点都与至少一个 Di 中的点相邻。

  • EiuVivVi 的所有边 (u,v)|Ei|ndi

  • E 是每个 Vi 中的点和任一 Di 中的点连接的边集。|E|=O~(n)

用 BFS 在 (V,EiE) 上计算 δi(Di1×V)1ik,时间复杂度为 O~(n2didi1)

考虑将 d(u,v)=min1ik{δi(u,ui)+δi(ui,v),δi(u,vi)+δi(vi,v)} 作为答案,其中 ui=argminwDiδi(u,w),vi=argminwDiδi(w,v),也即只考虑一侧。

  • 考虑 u,v 最短路上度数最大的点 x,令 i 满足 di1deg(x)<di,则 xVi1,xVi,因此最短路上的所有边 Ei。设关键点 wDi1x 相邻,则 δi1(u,u)δ(u,x)+1,δi1(v,v)δ(x,v)+1。如果我们按照这样做,只会得到一个 (2,2) 近似,因为 x 有可能恰好处于最短路的中点,导致两边都取到上界。但是我们发现由于 Ei 的定义是 uVivVi,我们可以找到度数第二大的点 x,令 i 满足 di1deg(x)<di,那么最短路地所有边也 Ei。因此,

    • δ(u,v) 为偶数时,一定存在不为最短路中点的 x,满足,δ(u,x)12δ(u,v)1δi1(u,u)12δ(u,v)δi1(u,v)δi1(u,u)+δ(u,v),因此 δi1(u,u)+δi1(u,v)2δ(u,v)
    • δ(u,v) 为奇数时,δ(u,x)12(δ(u,v)1)δi1(u,u)12(δ(u,v)+1)δi1(u,v)δi1(u,u)+δ(u,v),因此 δi1(u,u)+δi1(u,v)2δ(u,v)+1。不难发现取到上界当且仅当 x,x 是最短路最中间的两个点。

因此这是一个 (2,1) 近似。

时间复杂度为 O~(n2)

对于 (2,0) 近似,有

  • O~(n2.032) [Dory-Forster-Kirkpatrick-Nazari-V. Williams-Vos '23]。

  • O~(n2.25) 的组合算法 [Roditty 2023]。

续集

posted @   shiys22  阅读(378)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示