二级交错指数时间的电路下界
\(\newcommand{\NP}{\mathsf {NP}} \newcommand{\PP}{\mathsf {P}} \newcommand{\PPoly}{\mathsf {P/_{poly}}} \newcommand{\EXPSPACE}{\mathsf {EXPSPACE}} \newcommand{\SigmaTwo}{\mathsf {\Sigma_2}} \newcommand{\E}{\mathsf {E}} \newcommand{\F}{\mathsf {F}} \newcommand{\sv}{\mathsf {sv}}\)
为了研究 \(\PP \neq \NP\), 人类早期的一个尝试是转为研究如何取得电路下界, 也即转为考虑所有多项式大小的电路可以判断的语言 \(\PPoly\), 试图证明 \(\NP \not\subset \PPoly\).
为了先取得一些阶段性的成果, 这个问题有两个放宽问题的角度: 一个是先把 \(\PPoly\) 改成一些更弱的电路类, 另一个角度是把 \(\NP\) 先换成一些更强的语言.
一个数数论证可以轻易说明, 有一个 \(n\) 位的布尔函数需要 \(\Omega(2^n / n)\) 大小的电路, 有一些更加精细的构造说明了这也是上界. 问题在于数数论证给出的语言是非构造性的, 能否让某个图灵机判定的语言具有这样的复杂性呢?
一个比较平凡的事实是 \(\EXPSPACE\) 中可以找到一个 "最难用电路计算" 的函数, 对于 \(n\), 图灵机不妨从小到大枚举真值表 (长为 \(2^n\)), 然后枚举所有 \(< 2^n/n\) 的电路检查是否能够给出它. 如果不能给出, 那么就用这个真值表的结果判定输入.
在上个世纪, 人们早就做到了一个更精细一点的结果: \(\E^{\SigmaTwo}\), 也即一个 \(2^{O(n)}\) 时间的图灵机, 运行调用 \(\SigmaTwo\) 的神谕.
今年 9 月, 这个问题有了进一步的进展. WJMZBMR 陈立杰, 平原秀一 和 r_64 任瀚林 将 \(\E^{\SigmaTwo}\) 降到了 \(\SigmaTwo \E\): 两次交错, 但使用 \(2^{O(n)}\) 时间. (严格来说他们的工作还涉及一些其他的复杂度类, 在此不谈)
一个月后, 他们的工作又进一步被 Zeyong Li 改进了: 原来构造出的语言 \(\SigmaTwo \E\) 只能证明 有无穷多个 \(n\) 需要 \(2^n/n\) 级别的电路, 但新的做法则是对所有充分大的 \(n\) 都保证如此.
新的做法的灵感来源有很多, 从有界算术 (bounded arithmetic) 的研究到密码学中对于困难性的放大 (hardness amplification). 但最后的算法本身是很简洁漂亮的. 可以在这里用很短的篇幅讲清楚.
一个更一般的问题: 对偶鸽笼问题
鸽笼原理说的是, 把 \(n\) 个鸽子放到 \(m\) 个笼子里, 当 \(n>m\) 的时候, 一定有一个笼子里有至少两只鸽子.
相对而言, 它的对偶问题则是, 如果 \(n<m\) 的时候, 一定有一个笼子是空的.
这个问题的算法版本, 我们目前管它叫 range avoidance: 给定一个多项式大小的电路 \(C \colon \{0, 1\}^n \to \{0, 1\}^{2n}\), 能否找到一个 \(y\) 使得 \(y\) 不是任何一个 \(C(x)\) 的结果?
如果允许一点错误率, 这个问题惊人地简单. 只需要随机地选取 \(y\), 然后这个 \(y\) 只有 \(2^{-n}\) 的概率错误. 但确定性地做它就看起来不那么简单了.
一个简单的观察是, 这个问题是 \(\F \SigmaTwo \PP\) 的, 这是什么意思呢? 初看, 这是 \(\SigmaTwo \PP\) 的函数版本. 就是图灵机 \(M\) 首先接受一个输入 \(C\), 现在有一个可以输出的值 \(y\) 和它的证明 \(p\), 和尝试对它的驳斥 \(x\). 如果存在 \(y, p\), 对任意 \(x\), \(M(C, y, p, x)\) 都接受, 那么 \(M\) 给出了输入 \(C\) 的一个输出 \(x\).
那么看起来, range avoidance 显然是 \(\F \SigmaTwo \PP\) 的: 我们知道正确的 \(y\) 就够了, 不需要额外的证明, 然后如果 \(C(x)=y\) 就说明这个时候 \(y\) 并不是 "空的笼子", 驳回即可.
但上面这个问题定义出来的 \(M\) 的输出有一个问题: 它并不是确定性的. 对于任何一个合法的 \(y\), 它都可以被图灵机承认, 并不能选出一个典则的输出.
所以, 我们希望的其实是确定性的版本 \(\F \SigmaTwo \PP \sv\), 也即, 对于每个输入 \(C\), 都存在一个典则的输出 \(y(C)\), 这个时候存在一个证明 \(p\) 使得对于任意 \(x\), \(M(C, y(C), p, x)\) 都接受, 而当 \(y\neq y(C)\) 时, 无论是什么样的证明 \(p\), 都有 \(x\) 使得 \(M(C, y, p, x)\) 拒绝.
我们可以将这个概念按照博弈来理解:
- 多项式时间 \(M\) 是一个检验者.
- 给出 \(y, p\) 的人是一个证明者, 但它企图造假.
- 给出 \(x\) 的人是一个反驳者, 如果证明者说谎了, 那么反驳者可以找到一个 \(x\) 使得 \(M\) 拒绝. 但是如果证明者说的是真话, 那么反驳者就没有办法找到这样的 \(x\).
让我们首先来确定这样一个事实: 如果我们能给 range avoidance 找到一个 \(\F \SigmaTwo \PP \sv\) 算法, 那么就有一个语言 \(L\in \SigmaTwo \E\) 具有 \(\Omega(2^n/n)\) 级别的电路下界.
证明. 我们直接给出一个规约, 考虑这样一族电路 \(TruthTable_n\colon \{0, 1\}^{2^n/2} \to \{0, 1\}^{2^n}\), 意思是这个电路的输入是一个 \(O(2^n/n)\) 大小的电路的某种表示, 输出是这个电路的真值表. 记 \(N=2^n\), 显然这个电路在 \(N^{O(1)}\) 时间内被一个图灵机构造出.
那么我们对于这个 \(TruthTable_n\) 电路运行 range avoidance, 然后用得到的唯一可能的那个输出 \(y(TruthTable_n)\), 就是一个难以计算的函数.
这里的运行实际上是一个规约, 也即我们构造出那个 \(C=TruthTable_n\) 之后, 利用 \(\Sigma_2\) 的交错性完成前面的检验, 最后如果确认了这个真值表是被唯一确定的那个, 再由此判定输出. \(\square\)
于是, 问题的关键在于如何给 range avoidance 找到一个 \(\F \SigmaTwo \PP \sv\) 算法.
"分治"
我们首先考虑一个弱一点的结论: range avoidance 的一个 \(\F\PP^{\SigmaTwo}\) 算法. 这个算法的思路就是一步步猜出字典序最小的一个 \(y\): 如果 \(y_1 = 0\), 是否存在一组解?
这可以表示成一个二次交替的表达式, 也即 \(\exists y' \forall x\):
- \(y'\) 和 \(y\) 前缀相同
- \(C(x)\neq y\).
所以这是可以被 \(\SigmaTwo \PP\) 的神谕解决的. 我们现在逐位确定, 也就是执行 \(n\) 步, 自然在多项式的时间内完成了.
这也就是上个世纪解决的基本思路.
Zeyong Li 的思路则是考虑这样一个过程: 证明者的 \(p\) 是一个确定性的计算的计算过程, 这个计算过程的结论是给出了某个典则的 \(y = y(C)\), 然后反驳者的 \(x\) 就是试图指认证明者的计算过程是否有一步造假了.
一个简单的计算过程是行不通的: 考虑从小到大枚举所有 \(2n\) 长度的串, 这会导致计算过程的信息量很大. 为此, Zeyong Li 考虑了如下的分治想法.
算法
不妨考虑所有长为 \(2n\) 的串按照字典序排成一排, 然后把它们每个拆成两个长为 \(n\) 的串, 记为 \(x_0,\dots, x_{2^{2n}\cdot 2 -1}\). 然后我们定义这样一个分治的计算过程:
- MERGE(\(l, r\)) // 返回一个长为 \(n\) 的串, 或者报告 错误, 并得到一个答案 \(y\).
- 如果 \(l=r\), 那么返回 \(x_l\).
- 否则令 \(mid = (l+r-1)/2\), 计算 \(u=\) MERGE(\(l, mid\)) 和 $v = $ MERGE(\(mid + 1, r\)).
- 现在 \(u, v\) 各自是一个长为 \(n\) 的串, 尝试找到一个 \(x\) 使得 \(C(x) = u||v\):
- 如果确实存在, 返回 最小的那个解 \(x\).
- 否则, 报告 错误, 此时 \(y = u || v\) 使得 \(C(x) \neq y\).
首先, 这个计算过程是确定的, 并且它显然一定能找到一个不能被 \(C\) 表示的串 \(y\): 因为所有叶子处考虑了所有的可能性.
相应地, 它的牺牲在于, 它有可能找到的不是字典序最小的解, 而是有可能合并一些已有的解的时候发现不能合并, 所得到的解.
证明者的策略
为此, 证明者需要的信息被大大压缩了. 他可以只给出如下的计算历史:
- 在 MERGE 的节点处,
- 首先考虑错误在子树的位置发生的情况.
- 如果在左子树, 只需声称错误发生在左子树.
- 如果在右子树, 说明左子树没有发生计算错误, 此时需要声称左子节点的计算结果为 \(u\).
- 如果恰好在此节点发生了错误, 那么需要给出左右节点的计算结果 \(u, v\).
反驳者的策略
首先, 如果 \(u||v\) 确实是一个原像, 反驳者只需要给出这个原像就可以了.
否则, 其他的错误还有可能在于, 证明者声称的某个前面的节点计算出的结果 \(u\) 是错误的.
- 首先根据 \(u\), 可以通过 \(C(u)\) 得到两个叶子的值, 进而得到整个子区间 \(l\sim r\) 的值, 如果存在某个叶子的值计算错误, 那么反驳者可以给出这个这个叶子的位置, 然后检验者按照顺序检验, 发现确实有误.
- 否则, 其他错误还可能在于非叶子节点处, 给出的值并非字典序最小 的, 那么反驳者只需要给出这个节点的位置, 然后同时给出一个更小的原像, 这也是检验者可以轻易验证的.
综上, 这个证明--反驳--检验的策略只会筛选出算法 MERGE 第一个报告出的那个 \(y\) 来, 这说明了 range avoidance 是 \(\F \SigmaTwo \PP \sv\) 的!
一点注记
学过一点密码学的同学会发现, 这个把 \(C\) 电路套着用的过程, 就是 Goldreich, Goldwasser, Micali 用 \(n\to 2n\) 的伪随机发生器 (PseudoRandom Generator) 构造伪随机函数 (PseudoRandom Function) 的过程. 那个证明也需要证明, 如果这个伪随机函数可以被区分, 那么会导出一个对伪随机发生器本身的区分. 这个树的结构巧妙地让区分变得容易了.