图灵机是一种计算复杂性常用的一种计算模型, 图灵机由于结构简单并且功能完善而被广泛采用, 贯穿整个计算复杂性研究的始终.
这将是非常长的一个章节. 本节开始, 我们正式开始讲解现代复杂性理论. 当你看到一套科学理论中有"现代"这两个字的时候, 你应该做好心里准备, 因为这意味着它并不是那么容易懂. 这些理论是现当代著名科学家的重要研究成果, 需要花上一些时间去理解.
符号约定
符号 | 意义 |
---|---|
串 |
|
图灵机 |
|
所有图灵机的集合 |
图灵机计算模型
图灵机是一种计算复杂性常用的一种计算模型, 图灵机由于结构简单并且功能完善[^1]而被广泛采用, 贯穿整个计算复杂性研究的始终.
图灵机
我们前面已经看到, 自动机确实能解决一些判定问题, 即正则语言的判定问题. 那么, 正则语言到底有多少? 实际上我们会发现, 正则语言真的非常少. 判定一个语言是不是正则语言, 可以根据著名的泵引理(pumping lemma)来完成, 我们这里不对其进行正式介绍, 但是我们直接说明, 通过泵引理, 下面这一的简单的语言都不是正则语言:
图灵机(turing machine)是在自动机的基础上, 和用于记录数据(即符号)的纸带(tape)组成. 图灵机的纸带是无限长的, 并且一般来说是有起点的. 另外, 纸带是离散的, 就像是有一个一个的小格子. 纸带通过读写头(head)来进行操作, 且自动机可以控制读写头的移动, 且一般来说, 我们只允许每一步计算中, 读写头位置保持不变或移动一格. 与自动机不同, 图灵机中的转移函数要根据读写头下纸带上的符号来决定, 同时, 转移的结果也应当包含纸带的移动方向.
标准的图灵机只有一条纸带, 但是为了方便起见, 我们使用的是具有

定义
带图灵机 一个图灵机
是一个三元组 .
- 有限集
是字母表, 表示纸带可以记录的符号集. - 有限集
是状态集, 表示状态机的状态, 其中一个特殊的状态 为起始状态, 为停机状态. - 转移函数
我们依次来解释上述符号. 首先字母表和状态集很简单, 它类似于自动机的字母表和状态集. 图灵机在运行的时候, 首先需要向输入带上写入输入串, 然后再启动图灵机. 在启动图灵机时, 读写头处在纸带最左的位置, 而状态处于起始状态
图灵机的计算方式, 是转移函数来规定的, 每执行一步转移函数, 称为一步计算. 仔细看转移函数中的每条映射的内容, 左边有
注意: 图灵机的状态集是有限的, 纸带的条数也应该有限, 在你设计图灵机上运行的算法时, 你应该考虑该算法是否对于任意长度的输入都能被有限个状态集和有限条纸袋数目处理.
由于即使是非常简单的问题, 图灵机的精确描述(即写出它的状态集\转移函数\字母表)都回非常麻烦, 所有我们很少去精确描述一台图灵机, 取而代之, 我们用自然语言大致地叙述其功能. 对于这样的功能具体应该如何实现, 在学习计算复杂性时可以逐步积累. 常简的合法描述包括有例如:
-
将所有的读写头移动到最左的位置.
我们可以通过存放一个特殊的符号
在每条纸带的开头, 然后让图灵机进入一些列特殊的状态, 这些状态会不断地控制图灵机读写头左移, 知道所有的读写头都在符号 处即可. -
将某条纸带清空
这里的原理类似于上一条, 只是将移动(实际上就是写和刚读入符号一样的符号)改为写空格即可.
-
读到某些符号组合时停机
直接由一系列这样的转移函数控制: 处于任意状态并读到规定的符号转移到随机状态.
同时, 图灵机的描述不能过于抽象, 以免产生图灵机根本无法在规定条件下完成的指令:
- 在第一条工作带写下
的答案 - 计算Ramsey数
并写在第一条纸带上
图灵机和冯·诺伊曼计算机的关系
图灵机的纸带的功能类似于就是现代计算机的内存的功能. 现代计算机的内存有个重要的特点就是随机访问, 但是图灵机的纸带不能随机访问, 需要访问某个位置的元素时, 纸带上读写头需要逐步移动过去. 但是这并不影响我们使用图灵机来分析算法的复杂度, 因为实际上我们可以证明, 一台可以随机访问纸带的图灵机和一台标准的图灵机的计算速度之差一个多项式, 而且是一个很小的多项式. 即如果一个问题
图灵机的转移函数, 就相当于是CPU中的控制单元, 他们根据微指令(转移函数的前半段)来产生具体操作(包括内存的写入和寻址). 而图灵机的状态机, 就相当于是CPU的寄存器, 它表示CPU当且所处的计算状态. 现代计算机运算的最小单元是一个CPU周期, 而对于图灵机来说, 最小的计算步骤就是一步转移, 在这一点上二者也是很类似的.

这样看来, 似乎图灵机和标准的计算没有什么隔阂. 实际上, 丘奇-图灵论题将是一个比这个结论强很多的论题, 尽管尚未被证明, 但是目前为止它都未被证伪, 因此它成为了计算机科学的一条公理. 我们将在介绍可计算性的时候介绍这个结论.
Warming Up: 用图灵机计算二进制加法
现在我们来尝试构建一台用于计算两个数的加法的图灵机, 为了方便起见, 我们做如下限定:
-
两个数的位数相同
-
我们用特殊符号”
“来分割两个加数, 用” “来表示输入的结束. -
输入和输出都是从低位开始
如果你希望从高位开始, 你只需要多写几个翻转的程序即可.
-
每条纸带上的最左端的位置, 都有一个符号”
”这个符号我们永远不会改写, 它的唯一功能就是标注每条纸袋最左边的位置, 方面程序(转移函数)的构造.
-
有一个特殊符号”
“表示空格.
我们将工作分为两步完成:
- 拷贝第二个输入数到工作带
- 计算两个加数的和, 写在输出带上
在写好大致的工作步骤后, 我们需要写出更加详细的工作步骤, 来让我们更加详细地写出图灵机.
- 让输入带上的读写头向右移动, 直到找到符号”
” - 拷贝第二个输入数到工作带, 并以"
“结束 - 让工作带和输入带上的读写头向左移动, 直到均找到符号”
" - 计算步骤, 按位计算, 将结果写在输出带上, 并且将进位结果用状态机表示; 直到输入带和工作带都遇到"
" - 停机
现在我们来设计图灵机的状态机和转移函数. 我们用"
{% asset_img diagram-20190306.svg 计算加法的图灵机 %}
这个图相当复杂对吧? 我们做一些解释
- 首先, 图灵机从
处开始运行, 通过一步操作让输入带和工作带跳出 . - 在
处, 输入带上的纸带会不断右移, 直到遇见 . - 在
处, 输入带和工作带上的纸带会不断左移, 分别直到遇到 - 在
处, 如果输入带和工作带均抵达 , 则会右移动一步, 开始计算 - 在计算过程中, 每一步计算会根据上一步的进位结果, 以及输入带和工作带上的数, 决定当前位的和以及进位. 同时根据进位来选择计算状态
或 - 在计算时, 如果遇到
, 标志计算结束, 进入
此外, 在计算过程中, 遇到任何不符合上述步骤的情况, 均可断定输入是非法的, 此时图灵机直接停机即可.
即使是这样简单的问题, 解决它的图灵机描述出来也是相当复杂, 因此我们真的会很少这样描述, 因此建立对图灵机能力的直观感受对于研究计算复杂性来说尤为重要.
时间复杂度
在这之前, 我们先说一下, 对于图灵机来说, 计算时间意味着什么? 假如有这样一个世界, 这个世界里有各种各样的图灵机. 同我们的世界一样, 这个世界有它的时空规则, 图灵机们也有自己的信仰. 我们称这个世界为图灵世界(Turing Word). (这个故事和这种说法都是我虚构的, 学术界并没有这么叫, 只是我觉得图灵机很多地方真的可以和人类比, 因此我觉得讲出这个故事有助于读者理解, 如果你不喜欢这个故事, 你完全可以忽略这些内容而不影响阅读).
关于为什么要引入图灵世界 等了解了强丘奇-图灵论题后, 读者应该会觉得引入这个世界自然一些. 很多时候, 我们在讨论密码协议的时候, 我们都直接假设是Alice和Bob或者更多人之间的协议, 也就是人与人之间的协议. 实际上, 这些协议是图灵机与图灵机之间的, 之所以可以这么做, 是因为我们有强丘奇-图灵论题作为假设, 即人也可以看作图灵机, 也就是人, 图灵机, 电脑三者之间是"等同"的. 更多内容请参考对应章节.
我们来说图灵世界的时空观. 图灵世界是的时间是离散的, 即量子化的. 所有的图灵机, 在每个时间单位内, 都执行一步计算—-无论这个图灵机是复杂还是简单. 对于图灵机来说, 计算的时间就是计算的步数. 而每一步计算, 就是执行一次转移函数. 因此, 请等同这两个概念: 计算时间和计算步数.
时间函数
时间函数
设
是一个函数, 且图灵机 计算函数 . 称图灵机 在 时间计算 , 如果对于任意输入 , 在 时间内停机.
时间可构造函数
图灵机要怎么才能知道自己花了多少时间? 一种办法是, 让图灵机一边计算, 一边维持一个时钟. 图灵机有些计算步骤得花在维护这个时钟上, 另一些步骤用于计算. 那么, 我们可以根据时钟来规定图灵机在指定的时间停机. 对于固定的停机时间, 这一点并不难, 但是对于规定的停机时间也是一个函数, 问题就要相对复杂一些. 如果时间是一个和输入长度有关的函数,
时间可构造函数
函数
是时间可构造函数, 如果存在一台图灵机 满足 且在 时间内停机.
注意输入串
强时间可构造函数
函数
是强时间可构造函数, 如果存在一台图灵机 满足 且正好在 时间停机.
显然, 一个函数是强时间可构造函数, 仅当它是时间可构造函数.
带计时器的图灵机
如果一个函数
其他型的图灵机
图灵机相比自动机, 多了一些结构, 因此可以形成多种不同的变体. 但是, 如何界定图灵机是我们需要考虑的问题—-我们将多带图灵机视作了一种图灵机, 而标准的图灵机是单带的. 回忆<自动机模型>中的内容, 我们从来不认为"非确定自动机"是自动机, 但是为什么我们能容忍将多带图灵机划分到图灵机中? 为了回答这个问题, 我们首先介绍一些种类的图灵机, 再来考虑如何界定图灵机.
双向访问图灵机
我们之前介绍的图灵机, 纸带一头是无限延伸的, 而另一头确是有起点的. 现在有这样一种图灵机, 它的纸带双向都是无限的, 那么这样一台图灵机和标准图灵机有什么不一样? 为了简便起见, 我们只考虑单带双向访问图灵机. 现在, 我们证明由一台单带双向访问图灵机在
实际上, 上述命题的证明采用了"折叠"的思想, 即将一条可以双向访问的纸带, 用一条"折叠"了的纸带来表示. 你可以通过扩大字母表, 来使得它的每个位置都能放下两个字符. 如将双向访问图灵机的字母表
随机访问图灵机
我们假设我们使用的是双带随机访问图灵机, 即数据输入\输出\工作均在一条纸带上(这条纸带称为工作带), 但配备一条特殊的地址带. 在地址带上写上相应的地址, 然后再进入一个特殊的访问状态, 就可以使得图灵机的工作带上的读写头立即跳转到地址带上内容所标注的地址的内容.
健忘1图灵机
健忘图灵机是一类特殊的图灵机, 它们在结构上和普通的图灵机没有任何不同, 但是它们在针对具体输入数据时, 读写头运动的方式以及计算的总步数只与输入长度相关, 而与输入的具体内容无关. 换句话说, 也就是健忘图灵机在得到相同长的任意输入时, 读写头运动的方式, 以及从开始计算到停机所经过的总步骤数是相同的.
试想解密服务者为你提供了解密服务, 你可以询问他任何密文所对应的明文, 假设服务者是用图灵机来为你解密, 如果他的图灵机是非健忘的, 你输入不同密文时, 他给你明文的时间也就不同, 这就泄露了一定的信息. 但是如果解密使用一台健忘图灵机来为你解密, 无论你输入任何数据, 你拿到明文所需要的时间都是相同的-—-你无法从解密时间中得到和密钥相关的任何信息.
通用图灵机
图灵机和算法的关系
其实, 似乎每台图灵机只能解决一个问题, 并不像现代计算这样具有可编程性. 这样看来一台图灵机更像是电子计算机上执行的一个算法. 我们不妨换一个角度, 想一想你在计算机上求解一个具体问题时会怎么做呢? 首先是写一个程序, 然后再让计算机执行这个程序, 然后输入必要的数据并等待输出对吧? 试想一下, 如果将程序和数据一起交给计算机会怎样呢? 即我们将数据hard code到程序里面, 会怎样呢? 这个时候就可以将程序和数据一起看作是输入! 而计算机就是解决这个输入(程序+数据)集映射到的结果的函数计算器. 即计算机就是解决函数
试想, 我们是否也可以通过这样的方式来构造一台图灵机
图灵机的编码
在介绍通用图灵机之前, 我们首先要介绍如何来描述图灵机, 即我们确实有办法将一台图灵机
是一个满射, 即任何一个自然数 都能编码一台图灵机- 任何一台图灵机
, 都有无限多个不同的编码, 即 是无限集
我们记自然数
通用图灵机
定理
存在一台通用图灵机
满足
- 如果对于任意
, 在 时间内停机, 则 在 时间内停机
定理的证明将在专题中完成.
可计算性
可计算性是一个相对复杂但是有很有趣的话题, 要是单独拿出来写的话可以写成整整一本书. 在这方面, 丘奇可以说是先驱, 之后还有图灵, 哥德尔等很多史诗级的科学家研究. 本节, 我们将介绍可计算性的概念, 评估图灵机的计算能力, 以及应用一个重要的技术来证明问题的不可解性.
实际上, 这一部分并不是计算复杂性的核心内容, 因为我们很少关注不可计算的问题. 但是学习这一部分有助于理解图灵机的工作原理, 以及熟悉我们经常在计算复杂性\密码学\数学中使用的一个重要技巧: 归约(reduction).
对角化方法
现在介绍一个不可计算的问题, 然后我们将证明它不可计算.
定义函数
假设存在一台图灵机
图灵停机问题
图灵停机问题是一个经典的不能被图灵机解决的问题, 通过这个问题, 你会发现图灵停机并不是可以解决所有的为你, 即并不是所有问题都有解决的算法.
图灵停机问题
假设有一台图灵机
的计算如下:
首先调用 , 如果他输出0, 则 . 否则, 使用通用图灵机 来模拟计算 并输出 .
这里需要稍微说一下为什么要这么归约. 其实之所以我们不能计算
显然, 上述构造的
丘奇-图灵论题
图灵机不能计算的问题, 人能够计算吗? 也许你会觉得你可以穷举所有的答案. 并不是这这样的, 我们已知丢番图方程问题是图灵不可计算的, 那么如果给你一组丢番图方程, 你能判定他是解还是没有解的吗? 也许这个方程组的解会会非常大, 大到你穷尽一生也无法找到他的解, 也或许他根本就没有解——我们根本不能通过穷举来判定方程是否有解. 一些特殊的丢番图方程, 我们确实能找到求解或判定是否有解的办法, 但是对于所有的丢番图方程, 寻找通用的算法来判定它是否有解, 我们真的无能为力.
图灵停机问题也是一样, 也许你面前的图灵机陷入了一个非常大的循环, 比如需要
根据大量合理的计算模型构造, 最后都被证明计算能力和图灵机的计算能力等价, 我们有如下结论
丘奇-图灵论题
任何物理上可以实现的计算设施, 其计算都可以被一台图灵机模拟.
也即是说, 我们造不出来比图灵机更强的计算机. 这个论题虽然没有被证明, 但是也没有被证伪, 是计算理论的一条基本公理(或基本假设).
和
为了避免读者没有接触过可计算性的知识, 我们首先解释两个术语: 判定和识别. 我们说判定和识别的时候, 都是针对某个语言而言, 正如我们在之前的文章中提到, 语言和判定问题可以视作是等价的概念.
“语言
而"语言
这是我们最先接触到的一类问题, 虽然我们不去过多研究他们.
复杂度类
它表示那些能被一台图灵机判定的语言的集合. 类似地,
复杂度类
表示能被一台图灵机识别的语言的集合.
由于一个语言
可数和不可数
如果我们只证明存在一些语言不能被一台图灵机判定, 而不需要找出一个具体这样的语言, 一个简单的技术可以很快地解决这个问题. 这个办法需要用到数学上可数的概念, 我们仅做简要说明. 显然, 根据图灵机的编码方式, 我们知道, 图灵机是可数的. 由于语言(即二进制串的集合)是不可数的, 我们建立一个图灵机集合
计算复杂性
在计算复杂性理论中, 我们要做的事情的为问题根据其难度分类(或者称分层), 但在这之前我们需要回答的问题时, 问题是否真的有难度之分?
也许你曾经没有注意到, 有些问题真的很难, 因为试卷上让你求解问题真的都很简单—––我们这样说绝对没有针对你的意思, 因为我们所说困难, 不是你一个人做不出来, 而是也许所有人都做不出来. 现在, 让我们思考一下下面的问题.
命题
在任意6个人中, 至少有3个人相互之间认识, 或者相互之间不认识.
上述命题是可以被证明的, 只是他的证明还是相对比较麻烦, 如果你没有学过这个命题, 但是有良好的数学基础, 应该能够在半个小时内证明他. 但是, 5个人可以吗? 7个人可以吗? 或者我们换一种问法: 至少需要多少个人, 才能保证其中至少3个人相互之间认识或者3个人相互之间不认识. 这个问题可以被推广, 就是判定给定
问题
求问
是否是满足如下命题的最小正整数: 在任意 个点且边被染成红色或蓝色的完全图 中, 至少存在一个红色的 个点的完全图 或蓝色的有 个点的完全图 .
你可以试试当
我们以上介绍的问题中, 这些满足条件且
当然, 没人能说这个问题一定需要多少的步骤才能被解决, 也许有一个非常精巧的办法来解决他——这意味着这是一个相当简单的问题——这种可能是存在的. 但是, 好在我们对问题复杂度进行划分的时候, 考虑的是上界, 也就是说解决一个问题的更优算法可能被发现, 但是他不影响我们已有的对他的复杂度的断定. 例如, 复杂度类
复杂性与复杂度类
我们不需要对"复杂度类"这个概念做过多的介绍, 因为定义他们的模型很不相同. 但是, 我们会对每个复杂度类做精确的定义, 在这之前, 我们先介绍重要的符号
也许符号看起来有些复杂, 但是你要适应并学会翻译这种语言, 在这里, 我们用自然语言将它陈述一次. “
其中 是输入的长度
用自然语言来说,
这个多项式的系数次数是出现在
指数时间
指数时间是另一个复杂度类, 记作
类似地, 还可以定义双指数时间
实际上还可以定义
丘奇-图灵强论题
丘奇-图灵强论题
任何物理上可以实现的计算机器都可以被一台多项式时间内停机的图灵机模拟.
这句话是说, 物理上任何一台能够制造出来的计算机, 总能被一台图灵机模拟, 且存在一个多项式
这个论题也仅仅是一个猜想, 但是目前为止也是尚未被证明. 该论题直接限制了我们的计算能力. 好消息是, 量子计算机的出现对这一论题发起了挑战, 也许我们真的能算出那些我们之前认为不可能算出的问题.
时间谱系定理
你有没有想过, 是不是所有的
时间谱系定理 (Hartmains and Stearns, 1965)
设
和 是时间可构造函数, 且 , 则 .
时间谱系定理的证明看起来很繁琐, 但是其还是利用我们之前介绍过的对角化方法. (可以理解为将模拟输出翻转后输出的方法).
证明: 定义语言
设
根据上述定义,
, 根据 和 都是判定 的这一假设 , 根据 能够完整模拟 的计算
显然以上两个结论是矛盾的, 因此我们的假设”
由此也可以得出,
其他主题
有关时间复杂性的重要定理, 如Gap定理和加速定理及其证明, 将在专题中完成. 这些结论是计算机科学中非常"怪"的结论, 因为我们日常根本见不到这样奇怪的问题, 但是它们确实存在.
- 加速定理: (未完成)
- Gap定理: (未完成)
-
健忘是对oblivous的翻译, 一般有两层意思: 1. 无关, 如这里执行的操作与输入的数据无关 2. 不泄露信息, 如密码学中的Oblivious Transformation (abbr. OT). 实际上2.的解释是可以归约到1.的, 我们在讲解到OT时会作一些解释. ↩︎