Processing math: 0%

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

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

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

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

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

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

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

令图上每个点有 \frac 1k 的概率被选为关键点,点之间概率独立,则度数为 d 的点有 1 - \left(1 - \frac 1k\right)^d 的概率与一个关键点相邻。当 k = \frac d{c\log n} 时,1 - \left(1 - \frac 1k \right)^d \geq 1 - \frac 1{n^c},因此

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

其中 \tilde O 表示 O 忽略 \log

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

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

对图 (V, E),令

  • V_1 是度数 \geq d 的所有点。

  • D_1 是一个大小为 \tilde O\left(\frac nd\right) 的关键点集,使得每一个 V_1 中的点都与至少一个 D_1 中的点相邻。

  • E_1u \notin V_1 \vee v \notin V_1 的所有边 (u, v)|E_2|\leq nd

u \in D_1, v \in V,用 BFS 计算出所有 \delta(u, v)。时间复杂度 O(m |D_1|) = \tilde O\left(\frac{nm}d\right)。令 \delta(D_1 \times V) 表示边集 \{(u, v, \delta(u, v))\}

(V, E_1 \cup \delta(D_1 \times V)) 跑 Dijkstra。时间复杂度 O(n(|E_1| + n|D_1|)) = O(n^2d)

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

  • u \in D_1 \vee v \in D_1d(u, v) = \delta(u, v)
  • u, v 最短路不经过任何 V_1 中的点,d(u, v) = \delta(u, v)
  • 否则若经过了某个 w \in V_1,其相邻的关键点 w' \in D_1,则 d(u, v) \leq \delta(u, w') + \delta(w', v) \leq \delta(u, w) + \delta(w, v) + 2 = \delta(u, v) + 2

因此这是一个 surplus 2 近似。

时间复杂度为 \tilde O\left(n^2d + \frac{nm}d\right),令 d = n^{-\frac 12}m^{\frac 12},最终时间复杂度为 \tilde O(n^{\frac 32}m^{\frac 12}),一般图 m = O(n^2) 时为 \tilde O(n^{\frac 52})

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

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

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

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

对图 (V, E),令

  • d_1 \leq d_2.

  • V_1 是度数 \geq d_1 的所有点。

  • D_1 是一个大小为 \tilde O\left(\frac n{d_1}\right) 的关键点集,使得每一个 V_1 中的点都与至少一个 D_1 中的点相邻。

  • V_2 是度数 \geq d_2 的所有点。

  • D_2 是一个大小为 \tilde O\left(\frac n{d_2}\right) 的关键点集,使得每一个 V_2 中的点都与至少一个 D_2 中的点相邻。

  • E_1u \notin V_1 \vee v \notin V_1 的所有边 (u, v)|E_1|\leq nd_1

  • E_2u \notin V_2 \vee v \notin V_2 的所有边 (u, v)|E_2|\leq nd_2

  • E^* 是每个 V_2 中的点和任一 D_2 中的点连接的边集。|E^*| = \tilde O(n)

用 BFS 计算 \delta(D_2 \times V)。时间复杂度 O(m |D_2|) = \tilde O\left(\frac{n^3}{d_2}\right)

用 BFS 在生成子图 (V, E_2) 上计算 \delta'(D_1 \times V)。时间复杂度 O(|E_2||D_1|) = \tilde O\left(\frac{n^2d_2}{d_1}\right)

u \in V,在 (V, E_1 \cup \delta(D_2 \times V) \cup \delta'(\{u\} \times D_1) \cup E^*) 上跑 Dijkstra。时间复杂度 \tilde O\left(n\left(nd_1 + \frac {n^2}{d_2} + \frac n{d_1} + n\right)\right) = \tilde O\left(n^2d_1 + \frac {n^3}{d_2}\right)

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

  • u \in D_2 \vee v \in D_2d(u, v) = \delta(u, v)
  • u, v 最短路不经过任何 V_1 中的点,也即,最短路上的点度数都很小,d(u, v) = \delta(u, v)
  • 否则,若最短路经过了某个 w \in V_2(也即,最短路上有一个度数很大的点),其相邻的关键点 w' \in D_2,则 d(u, v) \leq \delta(u, w') + \delta(w', v) \leq \delta(u, w) + \delta(w, v) + 2 = \delta(u, v) + 2
  • 否则,若最短路不经过任何 V_2 中的点,但是经过了某个 w \in V_1(也即,所有点的度数都不大,但是存在度数中等的点),其相邻的关键点 w' \in D_1。令 w 是最短路上最后一个这样的点,w' 是那个 (w, w') \in E^* 的关键点。此时 u \to w 不经过任何 V_2 中的点,因此所有边 \in E_2(w, w'), (w', w) \in E^*w \to v(除了 w, v 自己)不经过任何 V_1 中的点,因此所有边 \in E_1。所以 u \to w \to w' \to w \to v 是一条被包含的路径,d(u, v) \leq \delta(u, v) + 2

因此这是一个 surplus 2 近似。

时间复杂度为 \tilde O\left(\frac{n^2d_2}{d_1} + n^2d_1 + \frac{n^3}{d_2}\right) = \tilde O\left(n^2\left(d_1 + \frac {d_2}{d_1} + \frac n{d_2}\right)\right)。后三者乘积为 n,令 d_1 = n^{\frac 13}, d_2 = n^{\frac 23},最终时间复杂度为 \tilde O(n^{\frac 73})

我们也可以把算法 2 看作仅考虑一个阈值 d_2,将 G' = (V, E_2) 直接应用算法 1,这样的总复杂度为 \tilde O\left(\frac{n^3}{d_2}+n^{\frac 32}(nd_2)^{\frac 12}\right),令 d_2 = n^{\frac 23},也可以得到 \tilde O(n^{\frac 73}) 的结果。

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

这个算法使用了两个阈值,将度数分为三层。立刻产生的想法便是可不可以通过分更多层来得到更优秀的复杂度,比如分 k 层就能得到诸如 O\left(\mathrm{poly}(k) n^{2 + \frac 1k}\right) 的算法。答案是否定的。因为在最短路所有点不经过 V_i 但经过了 V_{i-1} 时,如果我们选取最后一个 V_{i-1} 中的点,那么 w \to v 的所有边 \in E_{i-1},因此 Dijkstra 中要加入 E_{i-1},但是这样最终复杂度就会有一项 \tilde O(n^2d^{k-2})。因此这个做法下分更多层没有意义。

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

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

对于四种情况

  • u \in D_2 \vee v \in D_2,通过 \delta(D_2 \times V) 得到。
  • 最短路不经过 V_1 中的点,通过 (V, E_1) 上的 Dijkstra 得到。
  • 最短路经过了某个 w \in V_2,通过 \min_{w' \in D_2} \{\delta(u, w') + \delta(w', v)\} 得到。
  • 最短路不经过 V_2 中的点,但是经过了某个 w \in V_1,通过 \min_{w' \in D_1} \{\delta(u, w') + 1 + \delta_{(V, E_1)}(w, v)\} 得到。

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

\delta(V \times D_2) 视作矩阵,则我们需要求出 \delta(V \times D_2) \star \delta(D_2 \times V),其中 \star 表示 (\min, +) 矩阵乘法。对一般的 (\min, +) 矩阵乘,没有 O(n^{3 - \Omega(1)}) 的做法。

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

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

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

对图 (V, E),令

  • d_0 \leq d_1 \leq \ldots \leq d_k = nk 待定。

  • V_i 是度数 \geq d_i 的所有点。

  • D_i 是一个大小为 \tilde O\left(\frac n{d_i}\right) 的关键点集,使得每一个 V_i 中的点都与至少一个 D_i 中的点相邻。

  • E_iu \notin V_i \vee v \notin V_i 的所有边 (u, v)|E_i|\leq n{d_i}

  • E^* 是每个 V_i 中的点和任一 D_i 中的点连接的边集。|E^*| = \tilde O(n)

用 BFS 在 (V, E_i \cup E^*) 上计算 \delta_i(D_{i-1} \times V)1 \leq i \leq k,时间复杂度为 \tilde O\left(\frac{n^2d_i}{d_{i-1}}\right)

(V, E_0) 应用算法 1 得到 d'(u, v)。时间复杂度 O\left(n^2d_0^{\frac 12}\right)

求出 \min\limits_{\substack{w' \in D_i \\ 1 \leq i \leq k}}\{\delta_i(u, w') + \delta_i(w', v)\},假设 d 的选取足够分散,使得 k = o(n^\varepsilon),则复杂度为

\tilde O\left(n^{(2+(1 - \log_n d_0)+\omega(1 - \log_n d_0))/2}\right)

考虑将 d(u, v) = \min\left(d'(u, v), \min\limits_{\substack{w' \in D_i \\ 1 \leq i \leq k}}\{\delta_i(u, w') + \delta_i(w', v)\}\right) 作为答案。

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

时间复杂度为

\tilde O\left(n^2d_0^{\frac 12} + n^2\left(\frac{d_1}{d_0} + \frac{d_2}{d_1} + \ldots + \frac{d_{k-1}}{d_{k-2}} + \frac n{d_{k-1}}\right) + n^{(3-\log_n d_0+\omega(1 - \log_n d_0))/2}\right)

可知 \frac{d_i}{d_{i-1}} 都相等,令他们均为 2,则 k = O(\log n),符合要求。剩下的便是解方程,令 d_0 = n^{1 - r},则方程为 \frac 52 - \frac 12 r = (2 + r + \omega(r))/2,即 2r + \omega(r) = 3\omega(r) 是一个很复杂的函数,查表可以估计出 r \approx 0.427,最终复杂度 \tilde O(n^{2.2867})

如果不使用快速矩阵乘,直接用朴素的 \tilde O(n^{3 - \log_n d_0}) 来做,最终复杂度与算法 2 相同。

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


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

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

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

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

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

对图 (V, E),令

  • \mathrm{ball}(v) 表示离 v 最近的 b 个点。对每个 v 寻找 \mathrm{ball}(v) 的时间复杂度为 O(nb^2)

  • D 是大小为 \tilde O\left(\frac nb\right) 的关键点集,使得每个 \mathrm{ball}(v) \cap D \neq \emptyset

对每个 D 跑完整的 Dijkstra,得到 \delta(D \times V)

对于 u \in D \vee v \in D \vee v \in \mathrm{ball}(u)d(u, v) = \delta(u, v)

否则,考虑 w \in \mathrm{ball}(u) \cap Dd(u, v) = \delta(u, w) + \delta(w, v)

这是一个 stretch 3 近似。

时间复杂度为 \tilde O\left(nb^2 + \frac{n^3}b\right),令 b = n^{\frac 23},最终时间复杂度为 \tilde O(n^{\frac 73})

这是一个广为人知 (folklore) 的算法。更优秀地,stretch 2\tilde O(n^{\frac 32}m^{\frac 12}) 的做法,stretch \frac 73\tilde O(n^{\frac 73}) 的做法,stretch 3\tilde O(n^2) 的做法。[Cohen-Zwick '97]

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

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

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

对图 (V, E),令

  • d_i = 2^i0 \leq i \leq \log n

  • V_i 是度数 \geq d_i 的所有点。

  • D_i 是一个大小为 \tilde O\left(\frac n{d_i}\right) 的关键点集,使得每一个 V_i 中的点都与至少一个 D_i 中的点相邻。

  • E_iu \notin V_i \vee v \notin V_i 的所有边 (u, v)|E_i|\leq n{d_i}

  • E^* 是每个 V_i 中的点和任一 D_i 中的点连接的边集。|E^*| = \tilde O(n)

用 BFS 在 (V, E_i \cup E^*) 上计算 \delta_i(D_{i-1} \times V)1 \leq i \leq k,时间复杂度为 \tilde O\left(\frac{n^2d_i}{d_{i-1}}\right)

考虑将 d(u, v) = \min\limits_{1 \leq i \leq k}\{\delta_i(u, u'_i) + \delta_i(u'_i, v), \delta_i(u, v'_i) + \delta_i(v'_i, v)\} 作为答案,其中 u'_i = \operatorname{argmin}\limits_{w \in D_i} \delta_i(u, w), v'_i = \operatorname{argmin}\limits_{w \in D_i} \delta_i(w, v),也即只考虑一侧。

  • 考虑 u, v 最短路上度数最大的点 x,令 i 满足 d_{i-1} \leq \operatorname{deg}(x) < d_i,则 x \in V_{i-1}, x \notin V_i,因此最短路上的所有边 \in E_i。设关键点 w \in D_{i-1}x 相邻,则 \delta_{i-1}(u, u') \leq \delta(u, x) + 1, \delta_{i-1}(v', v) \leq \delta(x, v) + 1。如果我们按照这样做,只会得到一个 (2, 2) 近似,因为 x 有可能恰好处于最短路的中点,导致两边都取到上界。但是我们发现由于 E_i 的定义是 u \notin V_i \vee v \notin V_i,我们可以找到度数第二大的点 x',令 i' 满足 d_{i' - 1} \leq \operatorname{deg}(x') < d_{i'},那么最短路地所有边也 \in E_{i'}。因此,

    • \delta(u, v) 为偶数时,一定存在不为最短路中点的 x^*,满足,\delta(u, x^*) \leq \frac 12 \delta(u, v) \color{red}{- 1}\delta_{i-1}(u, u') \leq \frac 12\delta(u, v)\delta_{i-1}(u', v) \leq \delta_{i-1}(u', u) + \delta(u, v),因此 \delta_{i-1}(u, u') + \delta_{i-1}(u', v) \leq 2 \delta(u, v)
    • \delta(u, v) 为奇数时,\delta(u, x) \leq \frac 12 (\delta(u, v) -1)\delta_{i-1}(u, u') \leq \frac 12(\delta(u, v)+1)\delta_{i-1}(u', v) \leq \delta_{i-1}(u', u) + \delta(u, v),因此 \delta_{i-1}(u, u') + \delta_{i-1}(u', v) \leq 2 \delta(u, v) + 1。不难发现取到上界当且仅当 x, x' 是最短路最中间的两个点。

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

时间复杂度为 \tilde O(n^2)

对于 (2, 0) 近似,有

  • \tilde O(n^{2.032}) [Dory-Forster-Kirkpatrick-Nazari-V. Williams-Vos '23]。

  • \tilde O(n^{2.25}) 的组合算法 [Roditty 2023]。

续集

posted @   shiys22  阅读(380)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示