计算机
不是所有可以定义的东西都能被计算出来
计算机科学与计算机无关,就像天文学与望远镜无关一样
EDSGER DIJKSTRA
3.1 图灵范式
回顾过去,很长一段时间以来,人类对信息处理都不太好奇。动物在看到、闻到、触摸或听到时接受复杂的输入,然后以复杂的方式根据这些输入做出行为。人类的行为更令人困惑和难以理解。这样的现象我们每天都能观察到。人们很自然地会想:生物是如何处理信息并决定该做什么?奇怪的是,直到最近几十年,人们才开始对这个问题进行理解。然而,为我们的前辈们说句公道话,很明显,直到最近,任何试图研究信息处理的人都将受到一个基本障碍的阻碍——甚至没有办法明确提出这个问题。
这种情况直到20世纪30年代才有所改变,当时艾伦·图灵发表了一篇数学论文《可计算数及其在判据问题上的应用》,开启了历史上最重要的科学革命之一Entscheidungsproblem(英语中的decision problem)指数学家大卫·希尔伯特(David Hilbert)在1928年提出的一个关于判断数学逻辑中陈述的有效性的问题。然而,在他的论文中,图灵远远不止回答了这个问题。他提出了一个改变了我们看待世界的观念。通过它的技术影响,这个概念改变了我们的生活方式。他的发现是,计算,或处理信息的逐步过程的执行,可以被定义和系统地研究。从那时起,我们就走上了一条公认的道路,了解这些程序能做什么,不能做什么。也就是说,我们已经理解了计算。我们也一直在利用这种理解来生产技术,但技术不是我在这里关心的问题。
可计算性的技术概念有一个重要的区别:它是一件指定的事情,甚至是明确的,您希望从每一个数据输入的计算中得到什么结果。指定一步一步的计算来达到这个目的是另一回事。两者的区别并不明显。尽管如此,艾伦·图灵证明了存在一些问题,对于这些问题,我们想要的结果是明确的,但是对于这些问题,我们并没有一套循序渐进的指令,可以让你对每一个输入都得到正确的结果。这是一个惊人的发现。过去几十年的研究已经发展出一门丰富的科学,可以做出更细微的区分,尤其是在效率方面。事实证明,也有一些问题是不能有效地计算出来的,即使理论上是可以计算出来的。这一事实也带来了问题:我们不仅希望计算在原则上存在,而且希望在合理的时间内给出答案。为了得到这个结果,我们不应该等待数月,或数年,或直到我们的星系不再存在。
这些计算法则适用于所有的算法。因为算法是算法,尽管是一种特殊的算法,它们也必须遵循与一般计算相同的基本法则。这种对学习和进化计算的可能性和效率的终极限制的新科学,为理解这些学习和进化现象提供了一种基本的新方法,因为,不管它们是如何实现的——在硅、DNA、神经元中,或者完全是别的什么东西——有一些终极的逻辑法则限制了这些机制的作用。
图灵的论文包含了一些现在被视为计算研究基础的要素。首先,他描述了一个模型,现在叫做图灵机,它捕捉了他试图描述的现象,即机械的一步一步的过程。其次,他证明了在他的模型上可以实现的很有可能的结果。特别是,他展示了如何设计一个通用图灵机,能够执行所有可能的机械程序。正是这种普适性使得计算机技术如此普遍地有用,如果它不是现在凭借其有效性而如此普遍,那将是完全令人惊讶的。第三,图灵还证明了一个很强的不可能结果,即不是所有定义明确的数学问题都可以机械地解决。
图灵的“不可能”结果和它的普适性一样引人注目。它关注的问题是,预测一个任意的计算机程序和它的一个输入,这个程序在这个输入上启动后,是否会在有限的步骤后停止计算,而不是永远陷入循环中。这个所谓的暂停问题定义得很好。一旦我们指定了一种语言来表达程序,就不会有任何关于什么应该和什么不应该构成它的解决方案的歧义了。如果能够提前知道一个计算机程序是否会陷入一个永久的循环中,那就太好了。然而,正如图灵所表明的那样,任何图灵机都不可能解决所有的问题我们永远不可能例行地解决这个问题。
图3.1一个简单图灵机的例子。上面的图表描述了控制机器的程序。输入是在纸带上连续的正方形上的0和1序列。机器有三种状态q0、q1和qf。它以q0的状态开始,读/写头位于粗箭头指向的正方形上。如果这台机器是在州q0和头下的象征是1(最初是在本例中),然后通过箭头指示的路径q0节点的标签从1将开始,在这种情况下箭头标记(先生)端点。执行这个(1,mR)将导致方块的内容保持不变,并且头部向右移动一个方块。箭头的端点表示下一个状态仍然是q0。标记为(1,mL)的箭头的含义是相同的,只是头部向左移动。标记为(1,c0)的箭头意味着方块从1变为0,并且头部不移动。标签(0,mR), (0, mL)和(0,c1)具有类似的含义,当标题下的符号为0时适用。当达到最终状态qf时,计算将停止。读者可以通过这个例子验证工作,最终,当读/写头达到0 信号,机器会改变0 1和改变国家q1,然后将最终返回到起始位置,然后停止qf状态。(请注意,我们可以通过将(0,mR)箭头从q1改为q0而不是qf,来获得一个从未在此输入上停止的机器示例。)尽管图灵论文的三个特点——图灵机、通用性和不可计算性——都很重要,但如果把它们看作是我称之为图灵三联征的一类的实例,它们就变得更加重要了:一个明确的计算模型,捕捉了一些真实世界的现象(图灵的具体情况是机械计算),以及该模型的可能和不可能结果。学习、进化和智能都是计算过程的表现形式。就像在自然界中实现的那样,它们可能是微妙的,接近计算可行性的极限。在解开它们的秘密之前,我们可能需要对计算有相应的复杂理解。我的策略是为这些现象寻找图灵三合会。
3.2稳健计算模型
读者可能已经注意到,在前一节中有一个无法解释的飞跃。停止问题不能被任何图灵机计算的论断,等同于它不能被任何机械程序计算的论断。为了证明这一飞跃是正确的,需要一个被称为模型在变化下的稳健性的概念,这是计算机科学最深奥和最幸运的谜团之一。
我们已经看到,图灵方法的一个基本要素是定义一个计算模型,来捕捉现实世界的现象,在这个例子中是机械过程,包括那些没有人(或还没有)设想的现象。最后一部分是至关重要的:图灵的机器旨在捕捉人类在执行一项脑力任务时可以利用的所有过程,这项任务可以被认为是机械的,而不需要创造力或灵感。这种大胆的尝试吸引了许多人,他们想证明图灵的机器没有图灵所宣称的那样强大。然而,当不同的人试图定义他们自己对机械过程的概念,希望创造出更强大的模型时,他们所设计的所有模型,无论它们看起来多么不同,都可能被证明没有图灵机更强大的能力。例如,拥有两盘磁带、五盘磁带或一盘二维磁带并不会增加新的能量。同样,允许程序做出随机决定,或者允许具有量子力学建议的并行性的跃迁,也没有增加新的能力。为了找到比图灵机更强大、但仍然符合人们本能地认为的机械过程的模型,人们付出了大量的努力,但都失败了。因此,现在有压倒性的历史证据表明,图灵的可计算性概念在定义上是高度可靠的。这使得图灵的可计算性成为科学界最可靠的理论之一。
这种模型变化下的稳健性为我们的研究提供了基础和起点。对于学习和进化来说,鲁棒模型是必不可少的,就像它们对于一般计算一样。没有这种稳健性,任何模型或理论的价值都是值得怀疑的。我们对任意形式主义的性质不感兴趣。我们需要确保我们已经捕捉到了一些真实世界现象的特征。模型的健壮性是这种保证的唯一已知来源。
可计算性概念的发现,构成了发现世界真相的新途径。逻辑学家Kurt Gödel慷慨地承认,可计算理论“第一次成功地给出了一个有趣的认识论概念的绝对定义,即一个不依赖于所选择的形式主义的概念。3可以计算的内容不会随着模型细节的变化而改变。在后面的章节中,我将试图说服读者,出于同样的原因,其他概念也应该寻求类似的绝对定义,特别是学习和进化。
当然,我们没有理由相信,对于字典中有一个词的每一个概念,都存在一个绝对的定义,或一个健壮的计算模型,抓住了它的本质。的确,可计算性、易学性和可演化性可能是少数几个。对于大多数其他概念来说,还没有这样可靠的计算模型,尽管某些概念可能有一天会发现可靠的模型,但对于其他概念来说,可能根本就不存在这样的模型。我认为,自由意志或意识等概念能否通过本文所追求的算法方法成为理论问题,取决于能否为它们找到可靠的计算模型。
3.3计算定律的性质
图灵的贡献不仅仅是一系列具体的发现;他们提供了一种研究科学的新方法。在这一点上,他的重要性需要与艾萨克·牛顿相比较。牛顿对物理学的影响是无与伦比的,不是因为他描述了万有引力,也不是因为他有其他特别的发现,而是因为正是通过他的工作,人们才认识到,物理世界遵循的定律可以用数学方程来描述,通过解这些方程可以准确预测未来会发生什么。牛顿的理论不仅具有直接的通用性,而且被广泛地应用于机械系统。它们具有更高层次的超普遍性,因为它们为尚未构想的领域提供了发展理论的蓝图。从那时起,物理学家就一直遵循着用数学方程来表达物理定律的原则。电磁理论、广义相对论和量子力学并不是牛顿力学所暗示的,但它们遵循相同的智力模式:用数学方程表达的物理定律。从这个意义上说,方程提供了一种魔力,使一代又一代的物理学家对物理世界的理解超越了前几代人的梦想。自17世纪以来,物理学在其可以解释的现象范围内已经发生了好几次变化。即使牛顿的一些特殊发现已被取代,人们仍在以一种明显与牛顿所用的方法相似的方法来研究物理学。
没有人知道为什么在物理学中会存在这样的超一般性。在大多数情况下,只要认识到这一点就足够了。物理学家尤金·维格纳(Eugene Wigner)认为,我们只是在享受它的好处:“数学语言恰当地表述物理定律的奇迹是一份美妙的礼物,我们既不理解,也不配得到。”我们应该感激它,并希望它在未来的研究中仍然有效,无论好坏,它将扩展到我们的乐趣,即使可能也会使我们困惑,扩大到广泛的学术分支。
我预计,健壮的计算模型将在计算机科学中提供超一般性,就像数学方程在物理中的作用一样。它们将使各种各样的计算现象的范围和限制得以揭示。回顾过去,物理学在过去三个世纪中的所有发现都可以在牛顿的工作中找到,同样,在未来几个世纪中,许多新科学的发现都可以追溯到图灵。
我们可以对这两个领域做进一步的观察。物理学专注于理解基本过程的最小集合,这些过程足以解释物理世界的动力学,比如粒子在自然力下如何运动。相比之下,计算机科学则包含了更多样化的过程集——事实上,任何可以用逐步规则表示的过程。只要物体在物理定律下的轨迹可以通过逐步的规则来模拟,就像看起来的那样,计算将包含物理中所研究的所有过程。然而,计算过程虽然比物理过程更普遍,但也不是完全任意的。它们有自己的逻辑规律和局限性。支配它们的法律是我们在本章所关注的。
在图灵之前,数学被用于描述物理的连续数学所主导,在物理中(无论如何,经典的)变化被认为是发生在任意小的、无限小的增量中。然而,图灵机是一个离散模型。在他之前,离散数学很少被探索或发展;事实上,很少讨论图灵工作的影响是随后出现的离散数学。令人惊讶的是,对于我们将要在这里研究的现象,包括学习和进化,离散模型再次提供了最直接的稳健模型,并在分离基本现象方面最有用。连续模型最终至少会引起人们极大的兴趣,但是对于识别最基本概念所必需的初始探索来说,它们并不是最有成果的。
除了离散和连续的二分法之外,物理学和计算机科学之间还有一个更根本的区别。在物理学中,我们认为这个方程是不变的基本定律,它表达了这样的事实:两个物体之间的引力与距离的反比平方成正比,而与距离的其他函数没有关系。在计算中,我们在构造程序时有更大的自由。我们允许由一些基本步骤组成的任意程序。计算的永恒法则并不是对程序如何组成的约束。相反,就像停止问题的不可计算性一样,它们说明了任何特定类型的程序可以或不能实现什么。
图3.2在一个连续的模型中,有无限多的可能状态,这些状态相互平滑地联系在一起。左边的图显示了一个例子,其中每个状态都由曲线上的一个点表示。在离散模型中,状态不需要有这样的关系。右边的图显示了一个模型有四个状态,用圆点表示。
在计算中,定律是陈述,服从数学证明或反驳,但它们的相关性依赖于所讨论的模型的稳健性。人们可以把物理定律看作是类似于计算定律的。然而,就不受数学验证而言,物理定律在计算上对应的是关于模型稳健性的断言。物理定律和计算模型中的稳健性问题之间的共性也可以被积极地陈述——在这两种情况下,人们都需要超越数学形式来支持证据或证伪。
3.4多项式时间计算
一旦计算机变得更广泛地可用,并作出更广泛的努力来为它们编程,以比可计算性理论提供的更详细的细节来理解计算局限性的重要性就显得突出了。对这些局限性的研究被称为计算复杂性在这个领域中,我们不能仅仅区分用于特定任务的算法是否存在。一个还可以量化任何算法(如果存在)必须执行的步骤。
利用这个概念,人们可以根据执行这些任务所需的基本操作的数量,对熟悉的和不熟悉的任务进行分类。求两个数的乘积的长乘法过程是一个非常熟悉的算法,全世界的小学都在教授。在标准十进制记数法中,为了求n位数字的乘积,需要对单个数字对进行n2次基本运算,如图3.3所示。
对于长乘法,单个数字对的实际运算数可能是4n2、5n2或对某个固定数字c的cn2,具体取决于你认为什么是运算。然而,它不会比n2增长得快,比如n3或n4;它也不会像n1.9那样增长得更慢。我们可以用所谓的O符号来描述增长的顺序,而省略不那么重要的c值的细节。我们简单地说,长乘法算法是O(n2)算法。
一般来说,我们会区分使用多项式时间和使用指数时间的算法。它是多项式时间,如果它需要O(nk)基本步骤对某个常数k,其中n是需要写下输入的数字或位的数目。当然,如果k是一个很小的数,比如1或2,那就最好了。指数时间算法的形式为kn(例如2n或10n)。指数时间算法即使对于中等大小的输入也是不切实际的。例如,对于一个需要10n个步骤的任务,如果n只是30个步骤,那么就需要1,000,000,000,000,000,000,000,000,000,000,000个步骤。一台每秒执行一万亿步的计算机需要300亿年以上的时间才能完成,这是目前估计宇宙年龄的两倍多。同时运行多台计算机并不会对情况产生太大的影响。如果你用一台电脑来计算宇宙中的每一个粒子(目前认为宇宙中的粒子少于1090个),那么在这300亿年里,你就可以进行1090 × 1030,或者说10120次运算。对于一个需要10n步的任务,可以解决大小为n = 120的实例。如果我们将每台计算机的速度提高1000倍,那么我们只会将允许输入的大小增加3,从而得到n的极限为123。
图3.3当对两个有n个小数的数字进行长乘法时,这里n = 15,我们依次将第一个n位数字乘以第二个数字的每个n位,然后将结果相加。这都可以通过对个位数对进行n2个基本运算、加法和乘法来完成。然而,这些n2次操作看起来是重复的。这就提出了一个问题:是否可以用更少的操作来达到同样的结果?很难解释为什么这个非常自然的问题要等到20世纪60年代才被提出和回答。
关键是,像123这样的数字作为输入大小是非常适中的。一个123位数字的输入需要在这一页上写下少于两行。计算机的大多数应用需要更大的输入。例如,如果调度一个机队,那么输入的大小将以数千为单位。如果对从万维网读取的数据进行计算,比如分析关于某个主题的文章,那么输入的大小可能是数百万。在所有这些情况下,采用10n步的算法是完全不切实际的。即使我们拥有宇宙中所有的资源,也远远不够。
这类可以用多项式时间计算的任务或问题用大写字母P表示。两个整数相乘的任务因此属于这类P,因为它的标准算法,如我们所注意到的,需要O(n2)步,这是多项式。一般来说,P代表了在实践中可以计算的东西。
计算复杂性的基础是,人们想要得到的结果(比如,求两个数的乘积)与实现这个结果的多种可能方法之间的区别。还有一个基本的概念,即存在一些简单的特定问题,这些问题在图灵的意义上原则上是可以计算的,但对于这些问题,所有的算法实际上都是低效的。我们应该根据计算难度对任务进行分类的想法似乎是非常自然的,因此这个想法在计算机科学中起着核心作用。然而,这里有一个与传统科学教育相悖的暗示。在传统的数学和科学课程中,计算任务总是局限于那些容易计算的,如算术和线性代数。这种传统有一个明显的理由,那就是它只提供实用的方法。然而,沿着这些路线的传统教育确实留下了错误的印象,即每一个容易指定的问题都可以有效地解决。它没有让学生准备好面对全新的挑战,也没有让他们找到在计算上可行的方法。图灵在战时破译密码的工作集中在从加密信息中推断出原始信息的问题上,而没有对可能用于加密的大量密钥进行详尽的搜索。类似地,许多人们想要用计算机解决的自然任务,比如调度,涉及到从潜在的指数级众多解中找到最佳解。对于许多这样的任务,已知的是指数时间算法,但没有更快的。我们的科学文化仍在吸收这一现象的意义。
指数时间计算的不实用性是不言自明的。虽然实际可计算和不可行的边界并不清晰,但多项式时间准则是确定这一边界的最方便的地方。显然,具有高指数的多项式时间,如n100,在实践中与指数时间一样不可行的,即使是对于n的中等值。然而,多项式与指数的区别已被证明是非常有用的,原因很简单,因为大多数已知的算法都可以方便地在可行的低次多项式(如二次多项式,O(n2))和固有指数(如2n)之间二分。因此,由于不理解的原因,这个多项式与指数准则在实践中比它的简单定义所证明的更有用。经验表明,如果有人声称能够对任意大小的输入例行地计算函数,但又声称问题不在P中,那么很有可能还有更多可以说的,也需要说。也许输入并不是真的任意的,而是被限制在一个特殊的子类或一个概率分布中,对于这个问题确实可以在多项式时间内解决。经过进一步考察,人们往往可以解释这种出人意料的良好表现。事实上,当前计算机科学的许多研究都集中在确定情况的问题上,有时一次一个应用,在这种情况下,多项式时间计算可以在某些有用的意义上实现,即使不是完全通用的。
在定义计算时,还有一个更重要的区别。如果计算的每个步骤都是由之前的步骤唯一确定的,那么计算就是确定性的。在P的定义中,这是假设的。然而,在实际应用中,我们可以放松这种决定论的限制,允许计算时做出随机选择,就像扔硬币一样。这些算法仍然可能以高概率得到正确答案,即使不是完全确定的。所谓的随机算法,即对每一个输入都有很高的概率得出正确答案的算法,在实践中与确定性算法一样有效,所涉及的概率仅来自算法的抛硬币结果。这种算法只会在极少发生的抛硬币组合中给出错误答案,比如一千次抛硬币中只有三次正面朝上。此外,对于每个输入,错误发生的概率可以通过简单地重复算法足够多的次数而降低到指数级的小,错误发生的概率对于每个重复都是独立的。我们可以扩展标准确定性图灵机的定义,允许它们以这种方式根据抛硬币来做出决定。这些叫做随机图灵机。对于有界概率多项式时间,相应的多项式类称为BPP。P和BPP在数学上可能是相同的,在这种情况下,每一个使用随机化的计算都可以在多项式时间内被一个没有它的人模拟。P和BPP是否平等的问题目前尚未解决。
比BPP更宽泛的一类叫做BQP,表示有界量子多项式时间。这门课的灵感来自于量子物理学,它假设一个物理系统在某种特定意义上可以同时处于多个状态。人们自然会问,是否可以利用这种量子现象来加快计算速度。稍微简化一点,量子现象可能允许在一台量子计算机上同时进行100万次计算,而传统计算机需要在一台机器上以100万阶段一个接一个地进行这些计算,或者在100万台机器上并行进行。人们花费了大量的精力来理解多项式时间量子计算的威力。一方面,人们希望从数学角度更好地理解量子理论所提供的有限并行性的力量。另一方面,人们想知道这样的机器是否能在现实世界中被制造出来,因为量子计算机需要某些尚未被证明是可实现的能力。
图3.4一个随机算法的例子。人们可以通过在已知区域的正方形中画出任何形状的面积,向正方形随机投掷飞镖,并计算有多少部分属于这个形状来估计它的面积。这对任何形状都适用。所需要的是,飞镖击中正方形任何部分的概率都是一致的,并且连续的投掷彼此是独立的。得到一个糟糕的近似区域的唯一风险是运气不好,掷出的球不能代表均匀性。当一个人投出越来越多的飞镖时,出现这种结果的概率就会下降。随机化算法和BPP类本质上保证了成功。
我们可以把PhysP类定义为我们所处的物理世界允许用多项式时间计算的最大一类问题。确定PhysP类的极限似乎是我们这个时代最重要的科学问题之一。BQP是一个很自然的选择。如果事实证明它是不可实现的,那么BPP就是已知的最自然的选择。
虽然确定PhysP从根本上是一个物理学问题,但数学可能在解决它方面发挥作用。人们有可能通过数学证明P = BPP或BPP = BQP,甚至P = BPP = BQP。例如,这最后一种可能性将一次性地表明,多项式时间量子机器的能力并不比图灵定义的标准确定性机器的多项式时间版本更强,如图3.1所示。
我们知道的一件事是,这三个类-P、BPP和bqp本身在变化情况下都具有相当的健壮性。对确定性、随机化或量子计算的描述只能为每一类提供一个好的候选计算模型。这种随机和量子类的稳健性只有在答案是“是”/“不是”的问题上才知道。目前只剩下两个主要的候选问题,BPP和BQP,来解决物理世界中实际可计算的是/否问题。有两个候选者只是一个小尴尬,进一步缓解的事实是,已经确定在BQP,但不知道在BPP的自然问题的范围是有限的。
当然,如果我们不考虑多项式时间的限制,任何一种算法类型——确定性的、随机的或量子的——都可以证明与其他任何算法一样好。图灵机的特征鲁棒性仍然存在。在相反的方向上,如果我们在多项式约束之外施加越来越多的约束,以达到我们稍后将会遇到的学习和进化类,那么鲁棒性准则将变得越来越难以满足。
3.5可能的最终限制
我们前面描述的图灵方法在应用于整数乘法等特定任务时,包括以下三个部分。定义一个适当的模型来捕获计算任务的实际成本。证明可能的结果,在这种情况下,有效的算法的任务需要很少的步骤。证明一些不可能的结果,例如,对于定义的模型,没有任何算法需要少于这么多步骤。
有许多问题,我们希望有效地解决,但不知道如何。对于这类问题,最有效的算法采用的是指数步数,而不是多项式步数。当然,没有必要说明为什么目前已知的最佳算法应该是可能的最佳算法。让我们回到乘法的问题上来。基本的问题是:两个n位数相乘最有效的方法是什么?这个问题激发了一个研究项目,至今已经进行了半个世纪。1960年,在苏联工作的Anatoly Karatsuba发现了一种只需要O(n1.6)步的初始算法。对于n的大值,这已经大大改进了经典的O(n2)方法。整数乘法的速度比教给全世界儿童的标准方法快得多,这一发现是最近才发现的,这一点着实令人惊讶。
在最初的发现之后,很快就有了一系列的改进。这些在Arnold Schönhage和Volker Strassen于1971.9发表的算法中达到顶峰,该算法的运行时间接近但不是完全线性的-即O(n) -但优于O(n1+x)对于任何x > 0。这些发展的结果是,我们现在知道,整数乘法比之前几个世纪的任何人都有理由怀疑的更容易计算,当时只知道O(n2)方法,没有更好的怀疑。
令我们尴尬的是,我们还不知道乘法是否比加法难很多,而加法可以用标准方法在线性时间内完成。具有讽刺意味的是,在建立这样一个不可能的结果方面几乎没有进展(事实上几乎没有进展)。很明显,任何算法都需要查看两个输入数字的所有2n位,因此这个计算不可能在2n步之内完成。然而,仍然有可能存在线性时间算法用于乘法,比如对一位数数进行10n次运算,就像存在加法运算一样。对于输入和输出以标准十进制或二进制表示的整数乘法来说,解决这种线性时间算法是否存在仍然是理论计算机科学的一个主要挑战。是乘法本身就比加法难,还是只是表面上看起来难?
乘法是一个相对简单的问题,显然在实践中已经可以用古老的算法来计算了。关于多项式时间算法是否有一天会被发现的问题,我们目前只有指数时间算法的许多问题是在复杂性理论领域解决的。现在,我们将在本节的其余部分回顾其中的一些结果。读者可能会在计算机科学中发现这个有趣的背景,但它对以后的内容不是必不可少的。
一类著名的问题是所谓的NP,或非确定性多项式时间类。这些问题的特征是,对于这些问题,解决方案可能很难找到,也可能并不难找到,但是对于这些问题,候选解决方案很容易验证。例如,假设我们想要知道是否目标数x,说923年,可以被分解为两个小数字p和q的产物。那么,对于任何给定的候选人对p,问我们可以很容易的验证它们是否x的因素简单地乘以他们在一起并检查答案是否= x。(例如,给定候选数字71和13,就很容易确定71 × 13是否等于目标923。)但是,仅仅考虑到数字923,就没有找到71或13这样简单的方法。发现这些因素的一个naï ve方法是枚举所有小于目标x的数字,并测试每个数字是否能整除x。然而,对于n位数字,这将需要大约10n步。(目前已知的寻找n位数因子的最佳方法是n的立方根中的指数方法,这是一个相当大的改进,但仍然不是多项式。)
质数问题是确定任意数x是否有除自身和1之外的因数的问题。这是一个NP问题,因为对一个特定的候选解的验证可以在多项式时间内完成(即,正如我们所观察到的,给定一个n位数字x和另外两个数字p和q,我们可以在O(n2)步验证pq是否= x)。事实上,确实存在一些非常聪明的算法可以在多项式时间内确定一个数是否是质数。它们揭示出某些因素是否存在,但奇怪的是,揭示不出这些因素是什么因此,这个确定质数的特殊NP问题实际上也存在于P中。
目前,即使使用随机化(BPP),也没有已知的方法在多项式时间内找到因子。在测试因素是否存在的困难和发现因素是否存在的困难之间,经典计算的明显指数差距是广泛使用的密码方案的基础,特别是RSA密码系统在RSA系统中,你选择两个大质数p和q,将它们相乘得到它们的乘积x。然后你只公开结果x,而保留p和q的秘密。世界上任何看到x的人都可以为你加密信息,但只有你,知道p和q的人,才能解密任何这样的信息。关键是,生成任意质数p和q只需要生成一些随机数并测试它们是否质数。窃听者需要做的显然是更加困难的任务,即找到特定x的因子。(众所周知,这个分解问题在BQP中存在,或者在量子图灵机上可以用多项式时间计算。这一事实至少给建造量子计算机是否可行的问题带来了一些悬念。)
NP的重要性在于它抓住了心理搜索的一般过程我们称这些问题为心理搜索,因为它们可以通过搜索大脑或电脑内部产生的对象来解决。它们不需要在外部世界搜索,就像人们在万维网上搜索一个短语或在地下寻找石油一样。给定一个特定的问题,我们可以描述一组足够大的潜在解,任何真解都必须在这组候选解中。对于确定某个n位数x是否可以被分解的问题,可以将可能的解指定为整数{2,3,…,x−1}。找到答案只是一个简单的问题,一个接一个地测试每个数,看看它是否能除x。这种穷尽性搜索对于n的大值是不可行的,对于这个问题或任何其他问题。因此,对于任何NP问题,关键问题是是否有一种比穷举搜索更有效的方法来检测解的存在性。
质数问题确实有这样一个快速的替代算法,但它绝不是典型的NP问题。对于一个非常大的类,人们可以说对于大多数自然NP问题,没有已知的算法将它们放入P或BPP,甚至像因式分解问题BQP。值得注意的是,它已经证明了一个非常大的NP问题类的所有成员实际上是等价的,在某种意义上,一个多项式时间算法将会给另一个多项式时间算法。这个类还有一个显著的性质,即每个元素都是NP中最困难的元素。换句话说,对于这些所谓的np完全问题,目前没有人知道多项式时间算法来解决它们中的任何一个,但如果有人为任何一个找到了这样的算法,那么多项式时间算法将适用于NP.13中的所有问题。
这类np完全问题的一个例子是旅行推销员问题。这里有一张包含一些城市的地图,两对有直道的城市之间的距离,和许多x。问题是确定是否有一次旅游,遍历每一个城市,总距离不超过x。这个问题是NP因为给定一个候选人之旅很容易验证每个城市完全遍历一次,使用的道路总长度小于的奇幻之旅各种各样的调度问题提供了许多其他的心理搜索任务,我们希望我们有高效的算法,但我们现在知道,大多数是np完成的。np完全问题存在于数学的各个领域。例如,对于代数方程,我们有一个质数问题,给定一个n位数的整数c,方程xy = c是否有整数x和y的解,当然有些方程比这个更容易解。给定整数a, b, c,方程ax2 + bx + c = 0是否有整数解可以用二次方程的标准解式求解。另一方面,表面上类似的问题,即方程ax2 + by + c = 0是否有整数解x, y,是np完备的!14 . Yes, we are told only about the easy things in high school.是的,在高中我们只被告知那些简单的事情。
由于为NP完全问题寻找多项式时间算法的大量努力到目前为止都失败了,目前许多人猜想P≠NP,或者等价地猜想NP完全问题不存在多项式时间算法。(np完全问题同样也被推测不存在于BPP或QBP中。)这个猜想是否实际上是一个计算法则,就像图灵证明的停止问题是不可计算的断言一样,是潜在可解的,我希望有一天它会被证明或否定。假设P≠NP,虽然它在任何方向上仍未得到解决,但可以与同样没有被数学证明的物理定律相比较。当然,物理定律是不能用数学来证明的。这样的计算假设可以起到类似于物理定律的作用,因为我们可以很好地利用它们作为工作假设,至少在有人推翻它们之前是这样。在这种情况下,工作假设是多项式时间算法不存在于NPcomplete问题。当然,如果能找到一种有效的算法来解决所有的NPcomplete问题,那么证明这一观点不成立的可能性是非常大的,如果这种算法足够有效,将会产生革命性的后果。
在后面的章节中,当我继续考虑学习、推理和进化时,我将寻求遵循图灵三元组:建立一个健壮的计算模型,证明一些强大的可能性结果,并证明一些不可能的结果,以解释最终的局限性。在复杂性理论中,证明不可能的结果尤其具有挑战性。我们可能需要准备好假设某些算法定律,就像np完全性一样,而不能证明它们。这样的假设可以被视为工作假设,至少直到有人推翻它们,并出乎意料地愉快地发现,一系列目前被认为不可行的计算现象,实际上是可行的。
比NP更广泛的一类计算是#P(发音为“sharp P”)。这类问题列举了NP问题的解的数量。他们给出一个数字作为输出。这个类也有它的一类最难的成员,称为# p -完备问题,类似于np -完备问题。显然,对于np完全问题,计算解的数量至少和检测是否有解一样困难,因为答案将是一个数字,如果它大于零,那么我们就知道存在解。更有趣的是,在许多自然问题中,测试是否存在解决方案是在P中,但计算它们的数量是#P-complete。这意味着,虽然可以快速检测到解的存在,但计算解的数量与NPcomplete问题一样困难这类问题的例子在可靠性方面比比皆是——例如,人们想从组件的故障概率来确定一个复杂网络或系统的故障概率。由于某事发生的概率与它可能发生的方式的数量密切相关,这些问题可以被视为计数问题。事实证明这类# P至少是一样强大不仅NP而且量子类BQP.16因此仍有可能,但未被发现的多项式时间算法,计算所有问题存在于# P,因此还在BPP所有问题,BQP和NP。
 这些复杂性类的重要性源于另外一个事实,即它们有助于对自然发生的问题进行分类。许多出现的问题是心理搜索问题或相应的计算问题。事情就是这样,当我们遇到一个新的任务,我们想要解决,如果我们不能找到一个多项式时间算法,通常情况下,我们可以证明它是完整的(也就是说,是一个困难的成员)类NP或# P。从逻辑上讲,他们可能处于两者之间,但由于我们不理解的原因,他们很少这样做。因此,当新问题出现时,这个理论对实际解决问题提供了有用的指导。任何已知的理论都无法预测或解释为什么自然问题应该以这种方式被一分为二。这是一种维格纳式的神秘,我们既不理解也不值得,但应该感激并简单地享受。
图3.5说明了一些复杂类的相对计算能力,正如2013年所理解的那样。每个椭圆代表一类问题或任务。每个椭圆上的每个点都代表一个问题,比如检验数是否为质数,或者旅行推销员问题。斯蒂芬·库克在1971年发表的一篇具有历史意义的论文中首次以这种优雅的方式描述了自然问题。该图说明了以前未被怀疑的丰富结构,而现在已知的丰富结构在不同的问题中比比皆是。PAC类表示可学习的,是第5章的主题。
这些基本问题,关于这些复杂类的相对范围,与PhysP的实际范围密切相关,PhysP是宇宙物理上允许有效计算的一类。如果量子类BQP与PhysP相等,我们仍然想知道NP或#P是否属于这类,因此也被物理学所允许。因此,关于这些复杂类别的相对力量的问题也可以被视为物理问题。
3.6具有复杂行为的简单算法
最后,正如我们所看到的,算法的功能有一些限制。另一种说法是,我们指定想要计算的东西的能力要大于计算本身的表达能力。然而,尽管存在这些局限性,算法语言本身却具有很强的表达能力。图灵的结论是,存在可以模拟任何计算的通用图灵机,这清楚地说明了算法的惊人力量,这里讨论的算法是控制通用机的算法。
当然,我们已经看到了。丰富算法的另一个不同方面是,即使是一些非常简单的特定情况,也可能会有让普通人感到困惑的行为。下面是一个众所周知的简单过程的例子,到目前为止还没有进行分析:
1)从任意正整数n开始
2)重复直到n = 1:
(a)如果n是偶数,用n/2替换n。
(b)如果n是奇数,将n替换为3n + 1。
例如,从n = 44开始,我们得到如下序列:44、22、11、34、17、52、26、13、40、20、10、5、16、8、4、2、1。对于一个固定的起点,例如n = 44,计算结果序列的连续成员是很容易的。我们不知道的是,对于每个起始点n所生成的序列最终是否会达到n = 1并终止。自1937年数学家洛塔尔·科拉茨提出这个问题以来,人们已经尝试了许多起点。它们都导致了在n = 1时终止的计算。但是,有些令人震惊的是,考虑到这个问题的描述是如此简单,没有人能够提供一个证据,证明这个过程会在每个可能的起点终止,或者不会。
Collatz的问题是简单过程中明显固有复杂性的一个例子,即使是那些孤立于任何复杂环境的过程。在这种情况下完全可以删除输入的概念通过考虑复合过程为起始数字n = 2, 3, 4个连续的基本程序,将开始下一个数字序列时生成的前一个已终止n = 1。问这个复合过程是否能得到每一个起始数n,而不是在一个特定的n之后永远停滞不前,等价于最初的问题。从这个角度来看,我们不应该对停止问题的不可计算性感到如此震惊,因为停止问题需要能够对最终的命运做出某种预测,不仅仅是一个,而是任何一个计算。
3.7感知器算法
我们对计算复杂性这一主要主题的探索终于将我们带到了我们的目的地附近,即对算法的研究。我们最后的出发点是一个简单但重要的算法,就像Collatz的问题一样,它也有复杂的行为,但这些复杂性可以归因于它运行的外部环境。这个例子是感知器算法,由Frank Rosenblatt在20世纪50年代提出。
感知器算法在以下情况下操作。假设有一组可能的例子,每个例子都有特定的描述,进一步假设有一个标准,其中一些例子是真实的,另一些是错误的。例如,一个例子可能是一朵单独的花,而标准可能是这朵花是属于物种A还是属于物种b。感知器算法要求以某种方式描述这些例子。对于这种情况,我们假设描述由两个数字x和y组成,它们指定了其中一个花瓣的长度和宽度。
感知器算法在以下情况下操作。假设有一组可能的例子,每个例子都有特定的描述,进一步假设有一个标准,其中一些例子是真实的,另一些是错误的。例如,一个例子可能是一朵单独的花,而标准可能是这朵花是属于物种A还是属于物种b。感知器算法要求以某种方式描述这些例子。对于这种情况,我们假设描述由两个数字x和y组成,它们指定了其中一个花瓣的长度和宽度。
感知器算法在有某种数学标准(称为线性分离器)将两种可能的类别分开时起作用。这个标准,就我们的花来说,就是形式法则
px + qy > r
其中p, q, r都是数,使得每一个满足它的花都属于A种,而每一个不满足它的花都属于b种。例如,假设p = 2, q =−3,r = 2,那么规则是
2x−3y > 2
那么花瓣长5、宽2的花就属于a型,因为(2 × 5)−(3 × 2) = 4, 4 > 2。另一方面,由于(2 × 3)−(3 × 2) = 0且0 < 2,花瓣长3、宽2的花被划分为B型。图形而言,这意味着,如果所有的例子都绘制在二维空间中,代表由x和y的宽度,长度相对应的还有一条直线方程2 x−3 y = 2,这样所有的物种fl业主躺在这条线的一边,和其他物种B fl业主(或)。如图3.6所示。
当然,感知器算法并不预先知道分离器的真实方程。相反,它必须找到它。该算法通过扫描训练数据来工作,可能是多次扫描。在每一时刻,它都维持一个关于线性分离器的假设,其形式为ax + + >c。为了简单起见,我们将处理c = 0.20的情况。然后,算法从假设0x + 0y > 0开始。它逐个检查每个训练示例,如果当前假设正确预测了示例标签,那么假设不会改变。如果这个例子的标签没有被正确预测,那么这个假设就会被更新,以便在某种意义上“更有可能”,在这个相同的例子之后再次出现时是正确的。
图3.6斜线包含满足2x−3y = 2的点。点(x = 4, y = 1), (x = 5, y = 1),和(x = 5, y = 2)所有满足2 x−3 y > 2,并标记为“+”,而点(x = 1, y = 2), (x = 3, y = 2),和(x = 4, y = 3)不,标记为“−。”换句话说,物种A的花会在这条线下面,而物种B的花会在这条线上面或上面。
更准确地说,如果假设错误地将一个真正的例子(u, v)分类为负数(即,因为au + bv≤0),那么a通过添加u来更新,b通过添加v来更新。更新后的假设的左边将是(a + u)x + (b + v)y,如果在随后的数据运行中出现相同的例子(u, v),它将有(a + u)u + (b + v)v。总和的值将比之前大一个正值u2 + v2,因此“更有可能”在值上超过0,并正确地识别正数为真。对于相反的情况,当一个负数被误分类为正数时,a通过减去u得到更新,b通过减去v得到更新。这将会减少左边的值由u2 + v2如果相同的输入(u, v)以后再提出,因此将“有可能”小于0,因此导致正确的负面分类的可能性。
根据训练数据被输入感知器的顺序,它可以产生非常多不同的假设历史。关于感知器算法的一个有趣的事实是,尽管我们无法控制它的确切命运,因为我们让它在任意数据上自由发挥,但它还是取得了一些相当了不起的成就。在该算法首次提出后不久,阿尔伯特·诺维科夫证明了该算法的最基本的力量,即如果有一个真正的线性分隔符,那么该算法一定会找到它,或者另一个假设也能正确地分类所有的例子,在错误分类的次数有限之后。此外,在给定数据的情况下,可以计算出此类错误分类数量的上限。这个上界等于M/m2,其中M是训练集中最远的数据点到(0,0)点的距离的平方,M是边距。边距有一个更复杂的定义:它是任何数据点到该距离最大的线的分界线的最小距离。m在分母中的结果是,数据点离分隔符越近,这个过程可能犯的错误就越多。
该算法的重要性来自几个额外的事实。首先,它适用于M/m2的形式不仅适用于两个变量的问题,也适用于任意变量的问题。其次,在实践中,即使是被噪声破坏的数据,它也经常工作得很好。第三,有一些处理数据的一般方法,这些数据不是通过线性关系而是通过更复杂的曲线分离的。例如,假设这两个类别不是像图3.6中那样由一条直线分开的,但我们怀疑会有更复杂的曲线将它们分开。在二维情况下,我们可以尝试学习分隔符ax + by + cxy + dx2 + ey2 > f,其中x, y是变量,a, b, c, d和e是要学习的常数。这个不等式在x, y上不是线性的,因为它包含高阶项,比如x2。然而,如果我们不把变量集看作{x, y},而是把它看作{x, y, xy, x2, y2},它可以被看作是线性的。我们可以将给定的任意例子转换为一对数字{x, y},通过乘法将其转换为对应的五个数字{x, y, xy, x2, y2}。这样,感知器算法也可以直接应用于非线性可分数据。
这种线性化是一个重要的想法,它极大地扩展了感知器算法的适用范围,但它并不是看起来的万能药。如果有一些非线性项,我们知道它们是什么,那么就没有问题。但如果有许多项需要查找,那么这将带来更高的,可能是指数级的成本。
图3.7感知器算法在三个维度上运行的例子:+(4,1,1),−(1,2,1),+(5,1,1),−(3,2,1),+(5,2,1),−(4,3,1),依次重复三次。符号表示示例的标签。初始假设是0x + 0y + 0z > 0。第一个例子(4,1,1)代入初始假设的左边得到0,因此不满足它,正如第三列的负号所示。第一列表明第一个示例(4,1,1)的真实标签是正的。因此,算法将示例的坐标(4,1,1)添加到假设的系数(0,0,0)中,得到4x +1y +1z > 0作为更新后的假设。六个例子循环两次后,得到假设3x−6y−1z > 0。在第三个循环中,证实了这一假设满足所有六个例子。
任何例子(甚至是无限的例子)只会产生有限数量的错误,这一标准似乎并不适合人类学习。它提出了这样一个问题:在宣布学习算法成功之前,我们真正需要的是一个什么样的结果?这是我们将在第五章讨论的主要问题。然而,在我们到达那里之前,我们需要更普遍地看一下,对于一个自然现象,无论是进化、认知还是其他有趣的过程,一个计算上合理的、机械的解释是什么样子的。
但是感知器算法给出了一个很重要的直觉。学习是在许多步骤中实现的,这些步骤看似合理,但如果逐个孤立地看待,是无害的。这些步骤之所以有效,是因为有一个整体的算法计划。这些步骤结合在一起,可以达到某种程度的收敛。我们应该说进化是相似的。采取的许多小步骤没有太多意义。但有一个算法计划,因此采取一致的许多步骤确实取得了非凡的成就。