操作系统—计算机是什么?"如何把程序写好“这个问题是可计算的吗?

166 阅读10分钟

1.计算机是什么?"如何把程序写好“这个问题是可计算的吗?

  • 芯片:计算能源

  • 摩尔定律:计算能力的发展

  • 可计算理论:图灵机

    • 当然,在科学家们尝试发明计算机和芯片之前,他们必须回答一个问题,那就是计算或者程序可以用来 做什么?比如:计算可不可以用来做饭?换一个更专业的说法,做饭可不可以被计算?

  • 公理化体系和不完备性定理

    • 最早在 19 世纪初,德国著名数学家希尔伯特提出:这个世界可以建立一套完善的公理体系,由少数几 个公理出发,推导出所有的定理和推论。这样就可以逐渐通过这种方法将世界上的万事万物都统一到一 个体系中。 当然,这只是一个非常美好的设想,如果万事万物都可以用形式化(简单理解就是程序化规范化)的手 段统一到一套体系中,也就意味着计算能力将被无限扩展,只要给定足够的时间和空间,计算机就可以 完成任何工作。 但在不久后,美籍数学家哥德尔就提出了哥德尔不完备性定理,内容是:即便在完善的公理体系中仍然 可以找到不能被证明也不能被证伪的命题。 这让我联想到,一说谎,鼻子就会变长的匹诺曹。如果他说 “我说谎了”,那么他的鼻子应该变长还是变 短呢?对于人类而言,这个问题可以理解,但是对于计算机来说这个问题是不可以被计算的。 正是因为世界上存在着大量的这种 “公说公有理,婆说婆有理” 的问题,才让大家认识到计算不能解决所 有问题,所以:计算机能力也是有边界的。哥德尔的不完备性定理,让大家看到了世界上还有大量不可 计算的问题。

  • 图灵机和可计算理论

    • 于是人们意识到了需要一个理论,专门回答这样的问题:哪些问题可以被计算,哪些不可以被计算,这 就是可计算性理论,该理论是计算机科学的理论基础之一。 1936 年,被誉为人工智能之父的阿兰 · 图灵提出了图灵机,它是一种不断执行指令的抽象计算机。之 所以说抽象,是因为图灵并没有真的造出这台机器,而是把它当成理论去和大家探讨可计算问题。 图灵发现如果一个问题是可计算的,那么它的解决方案就必须可以被具化成一条条的指令,也就是可以 使用图灵机处理。因此,不能使用图灵机处理的问题,都是不可计算的问题。

      比如一个马达的控制程序是可计算的,因为控制过程是可以被抽象成一条条指令的(即可以写程序实 现)。比如程序可以先读入传感器的数据,然后根据数据计算出下面要进行加速还是减速。

  • 不可计算问题

    • 但当图灵机遇到 “素数是不是有无穷多个?” 这样的问题时,事情就变得复杂了。虽然,我们可以通过有 限的步骤计算出下一个素数。比如可以每次尝试一个更大的数字,然后通过一系列计算过程判断该数字 是不是素数,直到找到一个更大的素数。古希腊数学家埃拉托斯特尼就发明了筛选出给定范围内所有素 数的方法

      我们利用埃拉托斯特尼筛法找到的素数越来越多。但是,我们还是不能回答 “素数是不是 有无穷多个” 这样的问题。因为要回答这样的问题,我们会不停地寻找下一个素数。如果素数是无穷 的,那么我们的计算就是无穷无尽的,所以这样的问题不可计算。

    • 停机问题

      • 我们也无法实现用一个通用程序去判断另一个程序是否会停止。比如你用运行这段程序来检查一个程序 是否会停止时,你会发现不能因为这个程序执行了 1 天,就判定它不会停止,也不能因为这个程序执行 了 10 年,从而得出它不会停止的结论。这个问题放到图灵机领域,叫作停机问题,我们无法给出一个 判断图灵机是否会停机的通用方法,因此停机问题是一个经典的不可计算问题。

      • 我们可以把世界上想解决的事情都称作问题,解决问题往往需要消耗芯片的计算能力,这通常称作时间 开销,另外解决问题还需要消耗内存,称作空间开销。

2.计算能力的边界在哪里?

问题的分类

世界上有一类问题,无论我们消耗多少时间和空间也无法解决,这类问题就包括 “停机问题”,称作不可计算问题,我们无法用计算机精确地解决这类问题。世界上不可计算问题多,还是可计算问题多,也是一个不可计算问题,但直觉告诉我们一定是不可计算问题更多。 另外在可计算的问题中,有困难问题,也有简单问题,我们通常用复杂度来衡量,比如:“求数组第 10 个元素”,计算这种问题,时间开销、空间开销都不会随着问题规模增长,我们记为O(1);

求数组中的最大值”,计算这种问题,时间开销会随着数组规模线性增大,记作 O(N),N 是问题的规模;还有像 “求一个 n*n 矩阵的和”,如果 n 是规模,那么时间开销会随着问题规模的平方增长,我们称作 O(N2);当然也有更加复杂的数学模型,比如说 O(N3)、O(N4)、O(N100) 等。

3.P 问题 vs NP 问题

按照摩尔定律所说,人类的计算能力每 18~24 个月翻一倍,我们的计算能力在呈指数形式上升。因此,在所有可以计算的问题中,像 O(N1000) 的问题,虽然现在的计算能力不够,但是相信在遥远的未来,我们会拥有能力解决。这种我们有能力解决的问题,统称为多项式时间( Polynomial time)问题。我们今天能解决的问题,都是多项式时间的问题,下面记为 P 类型的问题

image.png

另外,还有一类问题复杂度本身也是指数形式的问题,比如 O(2N) 的问题。这类型的问题随着规模 N上升,时间开销的增长速度和人类计算能力增长速度持平甚至更快。因此虽然这类问题可以计算,但是当 N 较大时,因为计算能力不足,最终结果依然无法被解决。 由此可见,不是所有可以计算的问题都可以被解决,问题如果不能在多项式时间内找到答案,我们记为NP 问题。有一部分 NP 问题可以被转化为 P 问题,比如斐波那契数列求第 N 项,可以用缓存、动态规划等方式转化为 O(N) 的问题。但还有更多的 NP 问题,比如一个集合,找出和为零的子集,就没能找到一个合适的转换方法。其实说这么多,就是想告诉大家:如今还有很多问题无法解决,它的数量远远大于我们可以解决的问题,科学家、工程师们也只能望洋兴叹了。

4.人工智能

此外,包括停机问题、包括 NP 问题在内的很多问题,虽然不能解决,但可以努力让计算机的解决方案超过人类的水平,这就是人工智能。 比如下围棋,围棋盘是 19*19 的,共有 361!种情况,如果遍历 361!种情况,并进行打分,共有 10的 170 次方种可能,因此,我们的计算能力是远远不足的。但是如果使用人工智能方法对可能出现的部分情况进行概率判断,在不追求绝对精确的情况下,人工智能就可以超过人类选手。 AlphaGo 战胜李世石就是利用了基于概率的不完全解法,这种解法已经可以超过部分人类职业选手了,也就是说计算机的解法已经超过了人类。当然,人类的强项在于理解和分析,人有两种思维,归纳和假设,这两种思维都是计算机无法计算的。机器用概率理解围棋,局部来说机器下得更好,但是人可以制造机器,因此,人的感悟更有意义,谈不上孰优孰劣。 针对这种解决问题的方法,20 世纪中人工智能之父图灵,提出图灵测试,就是在一次人机对话中,随机抽样一部分的实验者和机器对话,如果这部分实验者有较大的百分比判断对面是人而不是机器,那这台机器就通过了图灵测试。在围棋领域,可以说,AI 通过了图灵测试。但围棋的 AI 不能下象棋,这也是 AI 的一个劣势。所以广义的 AI 还没有出现,现在出现的是在某个专业领域的 AI。

下面我们回到最初的问题:“可不可以计算一个人程序写得好不好?” 这个问题可以这样来思考,如果把问题降级,变成:“可不可以计算一个人写的程序会不会停机?” 这个问题就如同停机问题,无法计算,因此这是一个不可计算的问题。但是我们通过设立规则,比如检查缩进、检查函数的复用情况、检查类的命名情况,给写程序的人更好的建议。另外,我们也可以通过AI 技术,让机器在 “程序写得好不好” 这个问题的判定能力上,达到人类的水平,通过图灵测试。 综上,从绝对的对错角度去看,这是一个不可计算问题,因为它没有办法被完全解决;但是从图灵测试层面来看,虽然目前无法解决这个问题,但是我们有理由相信,在未来,计算机对这个问题的解决方案,是可以超过人类的

5.思考

可不可以构造一段程序证明停机问题无解?如果可以,请用自己熟悉的语言写出这段程序。

\