即便知道生命临近终结,也要对清晨的到来心怀感激,平静地度过余下的每个夜晚,为自己出生在这个世界而心怀感恩,为还留在这个世界上的人们祈福。
Immerman-Szelepcsényi Theorem: For any function ,
在证明之前,我们还是考虑一下这个定理表达了什么。
语言学中,有一个命题说:
所有人类语言都是上下文相关的 (Context-sensitive)。
而 Context-Sensitive Language (CSL) 恰好就是 NSPACE (n)。即:
这个定理说明了,上下文相关语言的补,还是上下文相关的。我们来着手证明它。
根据对称性,实际上就要证明一个命题:
而考虑到字符串被 NTM accept,实际上就是有一条通路从 NTM 的 start configuration 到 accept configuration。而要证明的 定义展开就是:
考虑到对于一个空间复杂度为 的图灵机,它的 configuration 的数量最多在(参考 Savitch’s Theorem 中的说明)。所以实际上,我们的目标就是找到一个非确定性 级别空间复杂度的算法,解决下述问题:
-UNCONN 问题:给定一个图 和其中两个结点,如果存在一条 path 从,则输出 NO。否则输出 YES。
之前在 Savitch’s Theorem 中,我们证明了存在一个确定性的 空间的算法,解决-CONN 问题。重新考虑当时的算法,由于确定型图灵机在处理递归时,需要使用栈保存 路径上所有的结点,方便下一步深度优先搜索。但对于非确定型图灵机,我们不需要这个栈,而是利用非确定性去猜测。这地方需要仔细理解一下。
譬如,我们把 压入栈,是因为想着有可能未来某一天要把 弹出,再去从 寻找。但是对于非确定性图灵机,我们已经 “同时” 从 1 访问到了,不需要一个一个访问,也就不需要存储 了。
我们 “多路并进” 式地往前走,但凡有一个分支到达了终点就接受。
说明,-CONN 问题在非确定型图灵机上,只需要 的空间复杂度。只需要存储目前走到了哪个结点就好了。
下面我们考虑 的非确定型空间复杂度,去解决-UNCONN 问题。
一个非常容易的错误就是,为啥我们不能利用 non-deterministism,去齐头并进地从 开始走,如果有一个分支走到了 就拒绝?
这是因为,需要仔细思考-UNCONN 问题的定义,它是一个 **"不存在"的问题,逻辑上等价于" 对于任意 "。而 NTM 的非确定性,是只要有一个分支 accept 就全局 accept,所以解决的是存在 ** 问题。故上述想法是不对的,不能因为某条分支没走到,就认为全局都不可能走到。
(其实上述误区就在于,“怎么把一个 NTM 的 accept 和 reject 交换”。它无法在很低的时间复杂度内完成( 未知)(因为需要知道所有 branch reject 才能 accept),但可以在很低的空间复杂度内完成 也就是这个定理证明的。)
下面我们考虑一个 nondeterminism 的算法,去计算函数:
注意,这是一个函数需要计算。即我们设计的 NTM 需要当且仅当一个 branch 输出 0 或 1,而其他 branch 都 reject。
这个算法其实是有点巧妙和令人费解的。这个 NTM 总是 accept 的,只不过 accept 后输出 0 还是 1。我们用这个函数输出去替代 “accept”、“reject”。
要计算:
-
非确定性地创建 个 branches,每个 branches 猜测了一个 bit mask(譬如)表示了对于每个, 是否存在一条长度 的 path。 表示猜测有,反之则没有。
-
对于每一个 branch,以及 bit mask 中为 1()的那些点,我们用-CONN 的图灵机去判定 是否存在一条长度 的边。
更具体地,这一步可以直接运行-CONN 的 NTM,如果该 NTM accept 则状态转移进入第 3 步;如果该 NTM 有任意分支 reject,则全局也 reject,说明这个 branch 的 bit mask 猜错了。
-
能进入这一步,说明每个 的点 都猜正确的了。但是对于 的那些点,我们并没有办法得知,是否真的不存在 的长度 的边,因为不存在是困难的。
我们存下来 bit mask 中 的个数。
注意,前三步可以在空间复杂度 内完成。因为我们只关心 bit mask 中 1 的个数,没必要把 bit mask 存下来。
所以实际上是一个一个点 分支产生,然后如果 就判定一下,如果正确了,就。
-
现在假设我们知道了一个数 " 走 步能到达的点的数量 "。(具体计算方法会在后面讨论)
(注意, 和 差异就在于, 是去除了 后、在当前分支猜测情况下算出来的,不一定是对的,但一定小于等于正确的值,而且一定有一个分支等于正确的值。)
然后我们讨论:
-
若,则 accept 并输出 0。此时 是正确的值,而且 和 中, 走 步能到达的点的数量是一样的,故输出 0。
-
若,则直接 reject。说明我们 bit mask 猜错太多了。因为正确的 最少为。
-
若,此时需要分类讨论:
- 若 真的存在一条长 的 path,则说明 猜测正确,则需要输出 1。
- 若 真的不存在一条长 的 path,则说明 猜测错误,存在一个点, 有一条长 的 path,但我们把他猜成了。
为了判别以上两种情况,我们直接运行判定-CONN 的 NTM,去判定是否存在 有一条长度 的 path。若该 NTM accept,则直接输出 1。若该 NTM 任意分支 reject,则全局 reject 这个分支。说明 猜错了,我们期待猜对了的那个分支去输出结果。
-
综上,可以认识到。所有分支中, 最大的那个分支的猜测结果是正确的。而且。而我们只希望正确的 那个分支输出结果。
下面我们说明整个算法,并且计算:
1 | count[0] = 1; |
上述算法就在空间复杂性 内解决了-UNCONN 问题。