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

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

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

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

先来考虑无权图上的 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_1\)\(u \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_1\)\(d(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_1\)\(V\) 的一般意义上的最短路,而可以强制所有的近似都采取这样的策略,那就只需要对最短路上的边和 \(w\)\(w'\) 的边跑 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_1\)\(u \notin V_1 \vee v \notin V_1\) 的所有边 \((u, v)\)\(|E_1|\leq nd_1\)

  • \(E_2\)\(u \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_2\)\(d(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\)。所以 \(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})\) 的结果。

注意在第四种情况中只有当我们选了最后一个这样的 \(w\),以及包含了 \(E_1\),才可以让处理 \(d(u, v)\) 时仅包含 \(\delta'(\{u\} \times D_1)\),否则需要 \(\delta'(\{u, v\} \times D_1)\),由于要对所有 \(v\) 求,因此只能把 \(\delta'(D_1 \times V)\) 全部加进去,但这样将失去任何复杂度优势。

这个算法使用了两个阈值,将度数分为三层。立刻产生的想法便是可不可以通过分更多层来得到更优秀的复杂度,比如 \(O(n^{2 + \frac 1k})\)。答案是否定的。因为在最短路所有点不经过 \(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})\)。因此这个做法下分更多层没有意义。也就是说,问题在于,虽然 \(\in E_{i-1}\) 是属于 \(V_{i-1}\) 一层的性质,但是我们把 \(E_{i-1}\) 要放入到整个 Dijkstra 中,层与层之间不独立。

因此,这个算法的优化点就在于,用全局的 \(E_1\) 避开了 \(\delta(u, w) + \delta(w, v)\) 而只使用其一侧。

但是,外在地,确实有更快速的矩乘算法,可以直接专注于优化这个式子本身。注意到这一步在 Dijkstra 中与其他部分独立。我们需要的只是 \(\min_w\{\delta(u, w) + \delta(w, v)\}\),如果我们能加速这一过程,那么便能加速复杂度。

更进一步地,如果这个过程足够快,我们就不需要用到算法 2 的策略了。这会是一个很有趣的事情,我们可以看到基本算法的复杂度关系是如何塑造最终算法的形态的。

\(\delta(V \times D_1)\) 视作矩阵,则我们需要求出 \(\delta(V \times D_1) \star \delta(D_1 \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]。

由于不需要算法 2 的策略,这个算法分多层是可以使复杂度变低的。

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

对图 \((V, E)\),令

  • \(d_0 \leq d_1 \leq \ldots \leq d_k = n\)\(k\) 待定。

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

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

  • \(E_i\)\(u \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})\)

最后,一个额外的事情是,我们可以将上面几个算法去随机化。上述算法均基于定理 1,考虑用别的方法替换掉它。考虑对一个点 \(v\),如果将其作为关键点,则 \(v\)\(v\) 的邻居都被覆盖了。我们总是从没有被覆盖的点中再考虑一个作为关键点,也即每次将 \(v\)\(v\) 的邻居删去,考虑剩下的图。如果限制从度数大的开始删,那么当删去了 \(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 D\)\(d(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 - 1\)\(O(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^i\)\(0 \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_i\)\(u \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\)\(d_{i-1} \leq 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)\) 近似。但是我们发现由于 \(E_i\) 的定义是 \(\vee\),度数第二大的点也可以以同样的方式被考虑。所以,
    • \(\delta(u, v)\) 为偶数时,\(\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) \color{red}{-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\)

因此这是一个 \((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 @ 2023-09-28 21:09  shiys22  阅读(278)  评论(0编辑  收藏  举报