[算法分析与设计] 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\) 间真实的最短路长度。
为什么我们只考虑 \(\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)\),令
对 \(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 的结果作为答案。
因此这是一个 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)\),令
用 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 的结果作为答案。
因此这是一个 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)\),令
用 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\),如果将其作为关键点,则 \(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)\),令
对每个 \(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)\),令
用 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)\),也即只考虑一侧。
因此这是一个 \((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]。