一些经典问题比暴力快一点点的算法

最长公共子序列 (LCS)

给两个长度 \(O(n)\) 的序列, 求它们的 LCS (longest common subsequence) 长度. 朴素 DP 是 \(O(n^2)\) 的, 与其类似的一个问题是编辑距离 (edit distance).

困难性

首先 OV (至于 OV 是什么, 待会再说) 被规约到了这个问题, 说明这个问题可能很难有 \(n^{2-\epsilon}\) 的算法.

但它的难度不止于此, 进一步地, (Abboud, Dueholm, Vassilevska, Williams, 2016) 证明了: 存在一个常数 \(M\), 如果 LCS 存在 \(O(n^2 / (\log n)^M)\) 的算法, 那么 \(\mathsf{NEXP} \not\subset \mathsf{NC^1}\).

由于现在认为 \(\mathsf{NC^1}\) 很强, 这个结论目前认为应该不是能够比较容易得到的. 注意 \(\mathsf{AC^0} \subset \mathsf{ACC^0} \subset \mathsf{TC^0} \subset \mathsf{NC^1}\), 现在人们得到了的本质上最好的结果一般被认为是 \(\mathsf{NEXP} \not \subset \mathsf{ACC^0}\) (Williams, 2010).

算法 (四毛子)

四毛子 (Method of Four Russians), 一般来说就是压状态.

我们这里仅讨论 \(|\Sigma| = O(1)\) 的时候的做法. 对于 DP 数组 \(f(i, j)\), 它的意思是 \(s[1,i], t[1, j]\) 的 LCS 长度 (或者编辑距离), 容易发现 \(f\) 的相邻两项差不超过 \(1\), 而且在递推一个局部的 \(f\) 的时候, 它依赖的 \(s, t\) 也都是局部的信息.

我们选定正整数 \(\ell\), 把这个数组打出横纵坐标是 \(\ell\) 的倍数的网格, 我们对于每个 \(\ell \times \ell\) 的块, 直接从左上两条边的信息推出右下两条边的信息, 这对于 \(s, t\) 只需要一些局部的信息, 而且这样总共不同的输入有 \(O(1)^{O(\ell)}\) 种可能, 如果把表全预处理出来, 我们可以把长为 \(\ell\) 的整数压成一个数, 这样可以看做是 \(O(1)\) 转移了.

这样的复杂度是 \(O(1)^{O(\ell)} + n^2 / \ell^2\), 取充分小的 \(\ell = O(\log n)\), 就得到了复杂度 \(O(n^2 / (\log n)^2)\).

(min, +) 矩阵乘法

这个不用太多解释了吧, 就是

\[(A*B)_{ij} = \min_k (A_{ik} + B_{kj}), \]

其中 \(A, B\) 是数值大小在 \(n^{O(1)}\) 范围的整数. 显然暴力是 \(O(n^3)\) 的.

困难性

APSP (all pair shortest path) 假设是说, 数值大小在 \(n^{O(1)}\) 范围的 APSP 计算问题需要至少 \(n^{3-o(1)}\) 的时间.

算法 (决策树)

考虑如何计算一个 \(n\times d\times n\)\((\min, +)\) 矩阵乘法.

对于 \(i, j, k, k'\), 我们需要知道 \(a_{ik} + b_{kj} \leq a_{ik'} + b_{k'j}\) 是否成立.

移项, 得到

\[a_{ik} - a_{ik'} \leq b_{k'j} - b_{kj}. \]

很神奇啊, 这个叫做 Fredman's trick! 我们只需要先把所有形如 \(a_{ik} - a_{ik'}\), 以及 \(b_{k'j} - b_{kj}\) 一起排序, 这样的数有 \(2nd^2\) 种, 然后就不需要再比较了!

最后我们还需要给 \(n/d\) 次乘法的总共结果取 \(\min\), 所以总共的比较次数是 \(O(n^2 d\log n) + O(n^3/d)\), 取 \(d = \sqrt{n/\log n}\), 我们就得到了 \(O(n^{2.5}(\log n)^{0.5})\) 次比较的时间计算 \((\min, +)\) 矩阵乘法.

不幸的是, 这个算法依然不能做到 \(n^{3-\delta}\), 因为我们并不知道不用比较的剩下的时间怎么快速找出那个最优的 \(k\).

但这个做法确实一定程度上可以去掉一些 \(\log\), 因为前面的做法虽然不能直接用, 但我们可以对于 \(k=(\log n)^{\delta}\) 的矩阵每个先枚举所有排序的决策树, 然后预处理出每个结果的对应答案.

这样可以给 \(n^3\) 除以一个 \((\log n)^{\delta/2}\). 适当调整一下块大小可以把这个做法卡到 \(O(n^3(\log\log n)^{c}/(\log n)^{1/5})\). (Fredman, 1975)

事实上, 这个思路进一步被研究出了 \(\tilde O(n^2)\) 次比较的 APSP, 以及 \(O(n\log^2 n)\) 次比较的 3SUM. 它们都可以通过爆搜决策树在一定程度上优化原问题.

算法 (\(\mathsf{AC^0}\) 电路的代数化)

\(\mathsf{AC^0}\) 电路是说这种电路只有常数深度, 多项式级别大小, 每个 AND, OR 允许接任意多个门.

这个算法由 (Williams, 2014) 给出. 比较神奇的是, 这是一个随机化算法.

考虑一个数 \(d = n^{o(1)}\), 我们希望能在比较快的时间内计算一个 \(n\times d\times n\)\((\min, +)\) 矩阵的乘法.

考虑输入是 \(n\times d\)\(d\times n\) 个长为 \(\log M\) 的 bit, 输出也是 \(n\times n\)\(\log M\) 的 bit.

接下来我们需要两个事实, 它是这个算法可行的关键:

  1. 两个数的加法可以用 \(\mathsf{AC^0}\) 电路计算.
  2. \(d\) 个数的最小值可以用 \(\mathsf{AC^0}\) 电路计算.

也就是说, 给定两个数列 \(a, b\), 那么计算

\[\min_i (a_i + b_i) \]

可以用 \(\mathsf{AC^0}\) 电路计算.

\(\mathsf{AC^0}\) 电路来说有一个好处, 就是它可以被一个 低次多项式 拟合, 这个拟合的意思是说可以按照某种方式随机找一个多项式, 让它在 \(\mathbb F_2\) 意义上和实际输出相等的正确率很高.

注意, 确切地相等是不能低次的, 因为 \(x_1\land \cdots \land x_n\) 就是 \(x_1 \cdots x_n\). 具体而言, 转换方式是选取 \(e\) 个随机向量 \(v_j\), 用

\[1+(1+v_1 \cdot x) (1+v_2 \cdot x) \cdots (1+v_e \cdot x) \]

来近似 \(x_1\lor \cdots \lor x_n\).

道理是这样的: 如果 \(x_i\) 全都是 \(0\), 那么显然这个式子输出一定是 \(0\). 否则, 每一项有 \(1/2\) 的概率是 \(0\), \(1/2\) 的概率是 \(1\), 它们乘起来后, 有 \(1/2^e\) 的概率是 \(1\), 于是取反之后, 就有 \(1-1/2^e\) 的概率是 \(0\). 所以我们就得到了一个 \(1/2^e\) 错误率的近似, 注意我们将多项式的次数压到了 \(e\)!

我们可以得到

(Razborov, Smolensky, 1987) 一个 \(\mathsf{AC^0}\) 电路可以被一个次数 \(O(\log n)^{\ell-1}\)\(\mathbb F_2\)-多项式以 \(0.99\) 的概率近似. 其中 \(\ell\) 是 AND, OR 的层数.

(这个是 \(\ell-1\) 而非 \(\ell\) 其实是纯卡常, 注意到最高层只需要 \(O(1)\) 的次数, 但下面的层有可能有 \(\mathrm{poly}(n)\) 个门, 因为要用 union bound 所以需要 \(O(\log n)\) 的次数.)

对于 William 的算法来说, 他还进一步用了一些 trick, 优化了一下电路, 使得这个电路里有 unbounded 的加法 (加法是不增加次数的), 以及一些其他的观察, 导致了:

结论. \(\min(a_i+b_i)\) 的计算可以被一个 \(O(\log (d\log n))\) 次多项式以高概率拟合.

这个多项式可以以很高的效率随机生成, 我们记它为 \(P_0(X, Y),\dots, P_{\log n}(X, Y)\), 下标代表输出的第几位.

接下来就是至关重要的一步了, 我们希望对于所有 \(A\) 的向量 \(a^{(i)}\)\(B\) 的向量 \(b^{(j)}\), 都计算出 \(P(a^{(i)}, b^{(j)})\) 的值. 把多项式 \(P\) 展开成形如

\[P(X, Y) = \sum_{u, v} P_{uv} X^u Y^v, \]

其中 \(X^u = X_1^{u_1}\cdots X_{d\log n}^{u_{d\log n}}\). 那么就可以把这看成一个关于所有 \(X^u, Y^v\) 的线性型, 我们可以对每个 \(a^{(i)}\) 计算出 \(\alpha^{(i)} = P(a^{(i)},\bullet)\), 我们需要两两计算出

\[\alpha^{(i)}(b^{(j)}), \]

这是一个 \(n \times (d\log n)^{O(d\log n)} \times n\) 的矩阵乘法. 也就是说中间的大小是

\[\exp O(\log (d\log n))^2. \]

而长矩阵乘法有快速算法.

定理 (Coppersmith, 1982). \(n\times n^{.1}\times n\) 的矩阵乘法有 \(\tilde O(n^2)\) 算法.

所以当我们设置合适的 \(d = \exp (c\sqrt{\log n})\) 的时候, 就有长矩阵大小是 \(n\times n^{.1}\) 的.

这个时候, 我们只需要做 \(n/d\) 次矩阵乘法, 所以我们就有

定理. \((\min, +)\) 矩阵乘法可以在

\[n^3 / \exp \Omega\left(\sqrt{\log n}\right) \]

时间内以高概率计算出.

学术界将这个方法称作多项式方法 (polynomial method). 它在上个世界末被用于证明一些 \(\mathsf{AC^0}\) 电路的复杂性下界, 直到 Williams 一举把 APSP 从除以 \(2\) 个 log 改进到 \(\omega(1)\) 个.

(Chan, Williams, 2016) 将这套方法得到的随机化算法得到了相同复杂度的去随机化结果, 所以我们现在是有这个复杂度的确定性计算的算法的.

(min, +) 卷积

考虑如何快速给两个序列 \(a, b\)\((\min, +)\) 卷积.

\(b\) 分成 \(n^{1/2}\) 块, 把一块和一个序列做 \((\min, +)\) 卷积的过程可以看做矩阵乘向量. 把 \(a\) 也分成 \(n^{1/2}\) 块, 就可以批处理这些块, 时间复杂度就是 \(n^{1/2}\cdot (n^{1/2})^3 / \exp \Omega(\sqrt{\log n})\), 也就是 \(n^2 / \exp \Omega(\sqrt{\log n})\).

正交向量 (OV)

正交向量是说给两组 \(n\) 个向量, 都是长为 \(d=O(\log n)\) 的 01 向量, 问是否有向量 \(a^{(i)}\cdot b^{(j)} = 0\).

显然暴力是 \(O(n^2)\) 的.

困难性

指数时间假设 (Exponential Time Hypothesis, ETH) 是说, 对于 \(k\)-SAT 问题 (有 \(n\) 个变量, \(O(n)\) 个约束, 每个约束是关于 \(k\) 个变量的), 对于 \(k\geq 3\), 存在一个 \(\delta_k > 1\), \(k\)-SAT 的任何算法需要至少 \((\delta_k-o(1))^n\) 的时间.

强指数时间假设 (Strong Exponential Time Hypothesis, SETH) 是说, \(\delta_k \to 2\), 可以认为是我们本质上不能比爆搜快多少地解决 \(k\)-SAT.

容易发现, 如果 OV 有 \(O(n^{2-\delta})\) 时间算法, 那么 \(k\)-SAT 都有: 把变量分成前 \(n/2\) 个和后 \(n/2\) 个, 每个约束看看前面的变量有没有满足, 后面的变量有没有满足. 这样就得到了解 \(k\)-SAT 的一个 \(O(2^{(1-\delta)n})\) 的算法.

所以, 如果 SETH 成立, 那么 OV 假设成立: OV 需要 \(n^{2-o(1)}\) 时间.

算法

目前最优的算法, 手段和 \((\min, +)\) 矩阵乘法类似. 由 (Abboud, Williams, Yu, 2015) 给出.

我们考虑两个向量不正交, 是说

\[\bigvee_{i=1}^d (u_i \land v_i) = 1, \]

那么我们把向量分成 \(g\) 个一组, 一组之间如果没有正交的, 就是说

\[\bigwedge_{i,j} \bigvee_k (a^{(i)}_k \land b^{(j)}_k) = 1, \]

我们还是把最外层 \(\bigwedge\) 用一个多项式 \(P\) 替换, 这个时候我们只需要 \(0.99\) 的概率近似 (之后多次重复实验取众数), 那么 \(P\) 的次数其实是常数. 同时, 第二层的 \(\bigvee\) 也用 \(O(\log g)\) 的次数多项式替换. 于是最后我们得到的多项式次数是 \(O(\log g)\) 的.

注意直接算多项式的项数, 我们得到的是 \((gd)^{O(d)}\), 算出来太大了, 但注意到我们是先选定 \(O(1)\)\(i, j\), 这部分给出的是 \(g^{O(1)}\) 项, 然后接下来更精确一点的说是选 \(d^{s}/s!\), 其中 \(s = O(\log g)\), 当 \(g = n^{\Omega(1)}\) 的时候, \(O(\log g) = O(\log n)\), 我们有

\[\frac{d^s}{s!} \leq O(d/s)^s = O(d / \log n)^{O(\log g)} = g^{O(\log (d / \log n))}. \]

所以总共只有 \(g^{O(\log (d / \log n))}\) 项, 当 \(g = n^{\delta / \log (d / \log n)}\) 是个足够小的 \(\delta\) 的时候, 我们可以调用 \(n\times n^{.1}\times n\) 的矩阵乘法.

于是, 设 \(d = c\log n\), OV 可以在

\[n^{2 - \Omega\left( \dfrac 1{\log c} \right)} \]

时间内计算. 注意这并不违反 OV, 因为这不是一个对任意大的 \(c\) 都保证 \(n^{2-\delta}\) 解决的算法.

3SUM

给集合 \(A,B,C\), 问是否有 \(a+b+c=0\).

算法 (决策树)

先把 \(A, B\) 都排序, 分成 \(n/d\) 个大小为 \(d\) 的块, 记为 \(A_i, B_j\).

对于每个 \(c\), 我们已经通过双指针把搜索范围限定在 \(\leq 2n/d\)\((i, j)\) 上, 只需对每组 \(A_i + B_j\) 上二分 \(-c\) 的值, 时间复杂度 \(O(n^2 \log d / d)\).

不能暴力预处理 \(A_i + B_j\) 的排序, 但注意到 Fredman's trick 已经告诉了我们, 想要知晓 \(A_i + B_j\) 的大小关系, 只需要之前对

\[S = \bigcup_i (A_i - A_i) \cup \bigcup_j (B_j - B_j) \]

排序, 比较次数 \(\tilde O(nd)\).

但是我们不能对每个 \(A_i + B_j\) 打表, 因为有 \(n^2/d^2\) 组, 处理每组也需要 \(d^2\) 的时间, 白干了.

但是注意到 \(d=\sqrt n\) 的时候, 我们获得了一个 \(O(n^{1.5}\log n)\) 次比较的做法. 我们可以对这个做法预处理所有决策树.

故技重施, 我们把实际问题分成 \(n/s\) 个大小为 \(s\) 的块, 注意到每个 \(A_i+B_j\) 落进的 \(C\) 的数量的总和是 \(2n^2/s\), 总共有 \(n^2/s^2\) 组, 所以每 \(s\)\(C\) 的询问一处理的话, 总共只有 \(O(n^2/s^2)\) 组要处理. 总时间是 \(O(n^2\log s/s^{1/2})\), 但预处理时间是 \(\exp(s^{1.5}\log s)\), 所以令 \(s = O((\log n)^{2/3} / (\log\log n)^{2/3})\), 我们就有了一个 3SUM 的

\[O\left( \frac{n^2 (\log \log n)^{4/3}}{(\log n)^{1/3}} \right) \]

做法.

不过这个不是目前最优的做法, 最优做法的复杂度是

\[O\left( \frac{n^2 (\log \log n)^{O(1)}}{(\log n)^{2}} \right), \]

由 (Chan, 2018) 提出, 还需要用到一些计算几何方面的技术.

积和式

积和式, 也即

\[\operatorname{per}A = \sum_{\sigma} A_{1\sigma(1)} \cdots A_{n\sigma(n)}. \]

可能你会选择 \(O(n2^n)\) 的 DP, 但同时间复杂度位置有个更好的做法是多项式空间的, 一般称为 Ryser 公式, 它的想法就是容斥: 二分图的左部每个人选一个点, 然后要求右边每个点都被选了至少一次, 所以可以被右边没选的点容斥, 这个容斥有 \(2^n\) 项, 稍微优化一下 dfs 过程就做到了 \(O(n2^n)\) 时间了.

困难性

首先 01-积和式是 \(\mathsf{\#P}\)-完全问题, 这个完全性在定义意义上是说把一个多项式时间图灵机 \(M\), 给定输入 \(x\), 数 \(y \colon M(x, y) \text{ accept}\) 这个问题直接规约到了积和式. 所以显然如果 01-积和式可以在多项式时间内计算, 就 \(\mathsf{P}=\mathsf{NP}\) 了. 还有一些进一步的结果, 比如戸田定理 (Toda 定理) 告诉我们 \(\mathsf{PH} \subset \mathsf{P^{\# P}}\).

比较有趣的是 \(\operatorname{per} A \bmod 2^k\) 对于固定的 \(k\) 是容易的. 而对于奇素数 \(p\) 来说, \(\operatorname{per} A \bmod p\) 依然是困难的, 如果对于某个奇素数 \(p\) 存在多项式时间算法, 那么只有唯一解的 \(\mathsf{NP}\) 问题 (一般叫做 UP, U 是 unambiguous) 会变得简单, 一般的 \(\mathsf{NP}\) 问题也会有高效的随机化算法. 这是因为从一般的 \(\# \mathsf{SAT}\)\(\operatorname{per}\) 的规约只乘了 \(2\) 的幂次.

Ryser 公式的魔改 (Bax, Franklin, 2002)

首先让我们先考虑一个奇怪的情况, 如果 \(A\) 是一个随机的 \(\pm 1\) 矩阵, 那么求和 \(p_1\cdots p_n\) 的每一项 \(p_i\) 就是一个均值为 \(0\) 的随机数整数, 方差 \(\leq \sqrt n\), 可以知道 \(p_i\)\(0\) 的概率有 \(n^{-1/2}\) 的量级, 那么 \(p_1\cdots p_n\) 不为 \(0\) 的概率其实只有

\[(1 - n^{-1/2})^n = \exp \left(- \sqrt n\right) \]

这么多! 这提醒我们, 按照某种合适的方式, 有可能让求和的项数减少许多.

接下来我们考虑 01-积和式.

我们按照这样一种视角来看待 Ryser 公式: 我们有 \(n\) 个单项式 \(f_i(x) =\sum a_{ij}x_j\), 那么 \(f_1(x)\cdots f_n(x)\) 是一个 \(n\) 次多项式, 我们刚好希望知道它 \(x_1\cdots x_n\) 次项的系数. 那么我们对每一维做个差分, 刚好得到的就是常数项了.

Ryser 公式无非是选取的差分的点为 \(0, 1\), 如果我们差分的点是 \(\pm 1\), 得到的就是

\[\operatorname{per} A= \frac 1{2^n} \sum_{x\in \{-1,1\}^n} x_1\cdots x_n f_1(x)\cdots f_n(x). \]

此外, 我们还可以把每个 \(f_i\) 加个常数项. 这不影响答案, 但会影响 \(f_i(x)\) 什么时候是 \(0\).

现在把 \(x\) 看成一个随机变量来理解, 对于每个 \(f_i(x)\), 由于 \(a_{ij}x_j\) 是有界随机变量, \(f_i(x)\) 作为一个随机变量, 可以被 Hoeffding 不等式控制, 可知 \(|f_i(x)| \geq n^{2/3}\) 的概率只有 \(\exp \left[-\Omega(n^{1/3})\right]\).

现在我们给每个 \(f_i(x)\) 加上一个随机数 \(c_i\) 得到 \(g_i(x) = f_i(x) + c_i\). \(c_i\) 就在 \([-n^{2/3}, n^{2/3}]\) 内均匀选取.

那么对于任何一个固定的 \(x\), 如果 \(|f_i(x)|\leq n^{2/3}\) 均成立, 每个项有 \(1/2n^{2/3}\) 的概率被命中 \(-c_i\), 那么这项贡献不为 \(0\) 的概率就有

\[\left(1 - \frac{1}{2n^{2/3}}\right)^n \approx \exp \left( - \frac{n^{1/3}}2 \right). \]

所以, 总贡献大概只有

\[2^n / \exp \Omega(n^{1/3}) \]

项. 但找到它们还需要花些时间, 经过一些设计, 可以得到一个

\[2^n / \exp \Omega\left(\frac{n^{1/3}}{\log n}\right) \]

的算法, 这里略去细节.

值得一提的是, (Björklund, Husfeldt, Lyckberg, 2017) 直接把这个思路改到了 \(\bmod p^k\) 上, 就得到了 \(\bmod 2^k\) 的一个 \(n^{k+O(1)}\) 算法 (之前 Valiant 只做到了 \(n^{4k + O(1)}\)), 以及一个对于固定的 \(p^k\)\(O(\delta^n)\) 做法.

CRT 与打表 (Björklund, 2013)

刚刚的做法有很大的局限性, 比如是个运行时间取决于随机种子的, 而且还只能做分量是常数级别的矩阵的算法.

考虑 CRT, 那就只需要解决 \(\bmod p\) 时候的积和式. 前面提到的 Ryser 公式并不会在 \(p\) 大的时候有很大帮助, 因为一个项是 \(0\) 的概率是 \((1-1/p)^n\), 当 \(p \sim n\) 量级的时候就完全没意义了.

积和式的另一个视角是它是一种可以进行自规约 (self reducing) 的式子. 也就是说一个 \(n\) 级别的积和式可以规约到计算 \(2^{n-k} n^{O(1)}\)\(k\) 级别的积和式.

首先让我们看看 \(k=n-1\) 的时候是为什么, 我们把置换看成环分解, 那么 \(1\) 这个点要么是独自成环: 这是 \(A_{11}\) 乘以子式的 per, 否则是在一个环里, 那构造矩阵 \(\tilde A = A_{ij} + A_{i1}A_{1j}t\), 只需要求 \(\operatorname{per}\tilde A\) 的一次项, 只需要对 \(t\) 插值就可以规约了.

一般地, 对于 \(k\) 级别规约, 考虑 \(\widetilde{A_{ij}}\) 定义为这样一个集合幂级数: 对于 \(S\subset[n-k]\), \(\widetilde{A_{ij}}[S]\) 是从 \(i\) 出发, 经过 \(S\) 里所有点恰好一次, 然后到 \(j\) 的路径权值和. 那么我们只需要对 \(\operatorname{per}(\widetilde A)\) 的集合幂级数的每一项都乘以剩下没经过的点集的积和式就行了.

我们还是用子集卷积挂一个元表示占据的点数的这个 trick, 再利用莫比乌斯反演求解, 这样只需要 \(2^{n-k}\cdot O(n^2)\) 个点值就行了.

考虑比积和式更加广泛的一个定义, 费米式 (fermionant):

\[\operatorname{fer}_k(A) = (-1)^n \sum_\sigma (-k)^{c(\sigma)} a_{1\sigma(1)}\cdots a_{n\sigma(n)}, \]

其中 \(c(\sigma)\)\(\sigma\) 的环长. 实际上费米式也是可以进行自规约的, 留作习题.

最后, 我们为什么要进行这样的自规约呢? 因为当 \(k\) 很小的时候, 我们可以直接打大小为 \(p^{k^2}\) 大小的表! 令 \(k = O\left(\sqrt{n/\log p}\right)\), 预处理打表的时间就可以接受了.

这样, 我们对单个 \(p\) 来说, 就在 \(2^n / \exp \Omega\left(\sqrt{n/\log p}\right)\) 的时间完成了 \(\operatorname{per}\) 的计算.

根据 CRT, 我们只需要让选取的 \(p\) 超过答案就能还原了, 当输入都是 \(\operatorname{poly}(n)\) 位的时候, 答案只有 \(\operatorname{poly}(n)\) 位, 于是只需要取最小的 \(\operatorname{poly}(n)\) 个质数, 复杂度

\[2^n / \exp \Omega\left(\sqrt{n/\log n}\right). \]

这不是目前最优的做法, 目前最优的做法是 (Björklund, Kaski, Williams, 2019) 在这个基础上进行了一个优化: 费米式是一个低次多项式, 我们需要的未必是 \(O(1)\) 查询点值, 而是通过某些信息快速还原出点值. 事实上这是可以在某些性质良好的素数上借助挂谷集合在 \(O(\log p)^{k}\) 时间内预处理, 并快速询问的. 所以 \(k\) 可以开大到 \(O\left(\sqrt{n/\log \log p}\right)\), 复杂度就优化到了

\[2^n / \exp \Omega\left(\sqrt{n/\log \log n}\right). \]

\(\mathsf{NEXP} \not\subset \mathsf{ACC^0}\)

首先回顾这两个复杂度类是什么.

左侧的 \(\mathsf{NEXP}\) 是非确定性指数时间, 也即 \(\mathsf{NEXP} = \bigcup_k \mathsf{NTIME}[2^{n^k}]\).

\(\mathsf{AC^0}[m]\) 是允许使用 unbounded fan-in 的 \(\land, \lor\) 以及 \(\bmod m\) 门 (即 \(x_1+\cdots+x_n\) 是否是 \(m\) 的倍数), 常数层, 多项式大小的电路, 不一致. 那么 \(\mathsf{ACC^0} = \bigcup_m \mathsf{AC^0}[m]\).

我们知道, 复杂度下界问题有三座大山: 相对化 (relativization), 代数相对化 (algebrization) 和自然证明 (natural proof). 之所以在这篇文章里讲 \(\mathsf{NEXP} \not\subset \mathsf{ACC^0}\), 是因为这个被 Williams 称为算法方法 (algorithmic method) 的手段通过一系列转化, 将线路复杂性下界和算法的精细设计联系了起来.

算法 \(\implies\) 下界

定理 (Williams, 2010).\(\mathscr C \subset \mathsf{P_{/poly}}\) 是某种合理的线路复杂度类 (这里可以姑且只考虑 \(\mathsf{ACC^0}\)), 如果关于输入数量 \(n\) 的多项式大小的 \(\mathscr C\)-可满足性问题可以在 \(O(2^n / n^{\omega(1)})\) 时间内解决, 那么 \(\mathsf{NEXP} \not\subset \mathscr{C}\).

注意 \(O(2^n / n^{\omega(1)})\) 这个时间是对于 RAM 模型来说的.

这个定理的底层架构依然是考虑反证法. 首先不妨设 \(\mathsf{NEXP} \subset \mathscr{C}\), 我们要理解这个包含关系会导致什么后果.

首先考虑 \(\mathsf{NEXP}\) 的一个完全问题, \(\mathsf{EXP}\) 无非是一个指数大小的计算过程, 可以证明如下问题是 \(\mathsf{NEXP}\)-完全的: 固定某个将一个字符串理解为多项式级别大小的电路的图灵机 \(M\). 然后问题如下: 给定一个电路, 然后考察它的真值表, 这关于输入是指数大小的, 然后在 \(M\) 将它理解成一个指数大小的 \(\textsf{3-SAT}\) 问题 \(C\), 问 \(C\) 的可满足性. 这个问题称作 \(\textsf{SUCCINCT-SAT}\) (简洁表示的可满足性问题).

简洁证据引理. 如果 \(\mathsf{NEXP} \subset \mathsf{P_{/poly}}\), 那么 \(\textsf{SUCCINCT-SAT}\) 有简洁证据 (succinct witness): 存在 \(S(n) \in \operatorname{poly}(n)\), 如果 \(C \in \textsf{SUCCINCT-SAT}_n\), 那么 \(M(\operatorname{TruthTable}(C))\) 这个电路 (按照 \(\in\) 的定义, 它是可满足的), 它的一组可满足的输入可以被一个很小的电路 \(D\) 的真值表给出, 也即它的大小 \(|D|\leq S(n)\).

(部分) 证明.\(\mathsf{NEXP}\subset\mathsf{P_{/poly}}\), 那么 \(\mathsf{EXP}\subset\mathsf{P_{/poly}}\), 根据 Meyer 定理, 有 \(\mathsf{EXP} = \mathsf{\Sigma_2 P}\), 进一步地, 根据包含关系

\[\mathsf{PSPACE} \subset \mathsf{EXP} = \mathsf{\Sigma_2 P} \subset \mathsf{PH} \subset \mathsf{PSPACE}, \]

可以得到 \(\mathsf{EXP} = \mathsf{PSPACE}\). 进一步地, 我们证明此时有 \(\mathsf{EXP} = \mathsf{MA}\). 方法如下:
因为 \(\mathsf{EXP} = \mathsf{PSPACE} = \mathsf{IP}\), 我们知道对于语言 \(L\in \mathsf{EXP}\), 可以由一个万能的 prover 和一个多项式时间的 verifier 完成, 进一步地, 这个 prover 一定也是 \(\mathsf{PSPACE}\) 的, 因为它显然可以搜索 verifier 的所有策略, 所以 \(\mathrm{prover} \in \mathsf{PSPACE} = \mathsf{EXP}\subset\mathsf{P_{/poly}}\), 可知存在一个多项式大小的 circuit 充当 prover. 接下来我们可以将 \(\mathsf{IP}\) 协议全部转换成单轮的 \(\mathsf{MA}\) 协议了! prover' 送给 verifier' 一个多项式大小的 circuit \(C\), 然后 verifier' 自己只需要模拟 \(C\) 和 verifier 进行交互的策略. 自然, 如果 \(x\in L\), 那么这个 \(C\) 是存在的, verifier 能够接受, 进而 verifier' 接受. 否则 \(x\notin L\), 那么任何 prover 都是无法说服 verifier 的, 那么 verifier' 一定也不会被说服.

反设简洁证据不存在, 设 \(C_n\) 是大小为 \(n\) 的电路里最难给出证据的, 那么对应的最小的证据电路 \(D_n\) 的增长规模是超多项式的. 这意味着 \(C_n\) 的真值表可以用作去随机化, 然后用对角线法导出矛盾, 详见 周紀寧 的笔记.

接下来是一个对角线论证. 首先考虑任何一个 \(L \in \mathsf{NTIME}[2^n/n^{10}]\), 可以构造一个多项式时间的规约, 把 \(L\) 里的任何一个问题转换成一个电路 \(C\) 判断是否有 \(C\in \textsf{SUCCINCT-SAT}\), 而且 \(C\) 生成的电路规模不超过 \(2^n\). (显然这里的 \(10\) 的具体数值不太重要, 重点在于我们大概只有一个 \(\operatorname{polylog} T\) 的膨胀因子就能做到这件事, 所以为了控制在 \(2^n\) 以内, 需要除以 \(n^{O(1)}\)).

接下来, 我们需要把 \(\mathsf{P_{/poly}}\) 全部转换成 \(\mathscr{C}\) 电路. 注意到 \(\mathsf{P}\subset \mathsf{EXP} \subset \mathscr{C}\), 而 \(\mathsf{P}\) 里有个问题叫做 \(\textsf{CIRCUIT-EVAL}\), 既然它现在属于 \(\mathscr{C}\) 了, 说明我们有一个万有的 \(\mathscr{C}\) 电路 \(C_{\mathsf{eval}}\) 来做电路求值, 那么把任何一个电路的编码喂给 \(C_{\mathsf{eval}}\) 的输入层就得到了该电路对应的 \(\mathscr{C}\) 电路.

于是我们可以看看如何更快地判定 \(L\) 了. 对于输入的 \(x\), 我们知道 \(x\in L\) 当且仅当它转换得到的电路 \(C_x\) 存在对应的多项式大小的电路 \(D\), 使得 \(D\) 的真值表给出了 \(C_x\) 所编码的 \(\textsf{3-SAT}\) 问题的一组合法解.

我们可以在定义 \(\textsf{SUCCINCT-SAT}\) 的一开始就选取这种容易检验解的编码方式: \(C_x\) 每接入一个输入得到的输出是具体的一个 3-clause, 这样对于每个 \(y\in\{0, 1\}^n\), 只需要根据 \(C_x(y)\) 输出的三个位置检查 \(D\) 的输出是否合法.

首先回忆定理的假设是: 我们一个 \(O(2^n/n^{\omega(1)})\) 的算法 \(\mathbf{A}\) 解一个 \(n\) 输入的 \(\mathscr{C}\) 电路的可满足性问题. 接下来, 我们具体的算法执行过程如下:

  1. 利用非确定性, 猜测一个电路 \(D\).
  2. 可以把完整的检验写成一整个多项式规模的电路 \(C'\). 也就是每个 \(y\), 要检查 \(D(C_x(y)[1]), D(C_x(y)[2]), D(C_x(y)[3])\) 这个 3-clause 是否都是对的. 这可以转换询问一个电路 \(C'\) 是否可满足.
  3. 根据前面的转换, \(C'\) 一定存在一个等价电路 \(C''\). 虽然我们不知道万有转换电路长什么样, 但是我们仍然不妨利用非确定性猜它. 注意这里 \(C'\) 是个传统电路, 我们仍然不能一次性完成, 而是需要不断局部地使用非确定性来完成. 每个节点 \(v\) 的输出可以看出一个多项式大小的电路, 所以它应该有一系列 \(\mathscr{C}\) 电路 \(C_v\) 和它等价. 那么作为基本单元, 我们每次先猜出 \(C_v\), 然后利用 \(\mathbf{A}\) 检验它是不是对的 (比如 \(v\)\(u\)\(w\)\(\land\) 的结果, 那 \(C_v \oplus (C_u \land C_w)\) 就是我们要用算法 \(\mathbf{A}\) 来检验的). 这只用了 \(n^{O(1)}\) 次, 所以花的时间依然是 \(2^n/n^{\omega(1)}\) 的. 是不是就是 DAG 上 DP, 哈哈.
  4. 检测 \(C''\) 的可满足性问题.

如果 \(x\in L\) 的话, 一定存在一个方案, 把中间猜的都猜对, 于是非确定性图灵机在 \(2^n/n^{\omega(1)}\) 的时间内接受. 否则要么猜的 \(D\) 是没有意义的, 那么可得无法通过最后的 \(C''\) 的检测. 要么中间 DP 的时候猜错了也直接无法通过检测.

总结下来, 我们的算法使用了 \(2^n/n^{\omega(1)}\) 的非确定性时间, 这说明 \(L\in \mathsf{NTIME}[2^n/n^{\omega(1)}]\), 总而言之我们就得到了

\[\mathsf{NTIME}[2^n/n^{10}] \subset \mathsf{NTIME}[2^n/n^{\omega(1)}]. \]

而足够精细的非确定性 时间层级定理 (Time Hierarchy Theorem) 指出这是不可能的, 我们就导出了矛盾. \(\square\)

这个定理大概可以被称为算法方法的开端, 它本身的证明就已经用到了复杂性理论的泰半家当: \(\mathsf{IP=PSPACE}\), 时间层级定理, 去随机化的一些技术手段等等.

\(\mathsf{ACC^0}\) 电路

我们首先需要对于 \(\mathsf{ACC^0}\) 电路的一个刻画.

定理 (姚期智 1990, Beigel–Tarui 1991).
存在算法, 对于深度为 \(d\), 使用的取模模数为 \(m\), 对于规模为 \(s\)\(\mathsf{AC}[m]\) 电路, 输出一个关于 \(n\) 个变量的如下意义的两层电路:
\(C(x_1,\dots,x_n) = f(A_1 + \cdots + A_K)\), 其中,

  1. 每个 \(A_i\)\((\log s)^{O(1)}\) 个变量的与.
  2. \(f\)\(0,\dots,K\) 映到 \(0, 1\), 其中 \(K = \exp ((\log s)^{O(1)})\).

而且计算 \(A_1,\dots, A_K\) 以及 \(f\) 的时间也是 \(\exp((\log s)^{O(1)})\) 的.

其中, 两个 \(O(1)\) 均和 \(d, m\) 有关.

这个定理某种意义上是 Razborov–Smolensky 的某种进一步结果, 我们暂且略去证明.

最后我们来解 \(\mathsf{ACC^0}\).

定理. 对于深度为 \(d\), 使用的取模模数为 \(m\), 存在 \(\delta > 0\), 对于规模为 \(2^{n^\delta}\)\(\mathsf{AC}[m]\) 电路, 可以在 \(2^{n - n^{\delta}}\) 时间计算可满足性问题.

证明. 对于给定的电路 \(C\), 考虑枚举前 \(n' = n - 2n^\delta\) 个变量. 那么我们需要缩掉后面 \(2n^\delta\) 个变量, 直接对每种取值的结果或起来, 这得到一个电路 \(C'\), 是一个 \(d+1\) 层, \(2^{3n^\delta}\) 项的电路.

首先根据 姚–Beigel–Tarui, 我们先转换成两层电路. 现在我们存在 \(c\) (和 \(\delta\) 无关), 把电路 \(C'\) 转换成 \(2^{n^{c\delta}}\) 个项. 转换也在 \(2^{n^{c\delta}}\) 时间内完成.

现在注意: 给多项式 \(P(x_1,\dots,x_{n'}) = A_1 + \cdots + A_K\) 的所有变量的进行求值就行了, 每种情况求值就是 FMT, 我们可以在 \((2^{n^{c\delta}} + 2^{n'}) n^{O(1)}\) 时间内完成!

\(\delta < 1/c\) 的时候就有了我们的结论. \(\square\)

于是我们就有了下界.

推论 (Williams, 2010). \(\mathsf{NEXP}\not\subset \mathsf{ACC^0}\).

参考资料

似乎有些做法是教学意义的, 来自 Timothy M. Chan 的 Algorithms from the Fine-Grained Perspective 课件.

其他还有些内容应该都可以搜论文搜到.

posted @ 2023-08-02 01:33  EntropyIncreaser  阅读(2401)  评论(4编辑  收藏  举报