经典证明:Chaitin定理 不可能编程判断代码的最简性
2009-02-17 23:17
281 查看
今天学到一个好玩的东西。仿照停机问题的研究方法,我们可以想出很多有趣的不可解问题。Gregory Chaitin曾经提出过下面这个问题。如果两段代码运行之后能够输出相同的结果,我们就称较短的代码比长一点的那个更简洁(注意,如果程序需要读入数据,读入的数据也算进代码长度)。对于一个指定的输出,一定存在一个“最简的”代码,它是所有能输出此内容的程序代码中最短的一个。在刚刚结束的TLE比赛中,参数选手拼了命地缩减每一个字符,写出来的代码一个比一个短。有人或许在想,这些代码究竟能短到什么程度?你如何才能知道你的代码已经不再有改进的空间了?受此启发,我们的问题出来了:你能否编写一个程序,使得该程序能够判断任意一段代码是否是最简的?
Chaitin定理指出,上述问题是一个不可解问题,再牛的人也不可能编写出这样的程序。证明方式与大多数此类问题一样,都是采用反证加构造的方法证明的。你能想到这个证明方法吗?
假设我们有一个程序A,该程序能读入一段代码并且判断该代码是否最简。写一个程序B,该程序读入一个自然数N,然后枚举出所有长度大于N的程序代码并用程序A进行检测,直到找到一个最简的代码;然后运行这个最简代码,输出和这个最简代码一样的输出内容。现在,运行程序B,输入一个比程序B的代码长度更大的数,让程序B去找一个比它自身更长的最简代码。但是,程序B比这个最简代码要短,输出内容却和它相同,于是矛盾就产生了。
但是,有没有可能程序B没有输出呢?换句话说,程序B会不会根本找不到一个比它长的最简代码呢?当然不会,因为最简代码显然有无穷多个。
补充一下:有人没明白这里“最简代码有无穷多个”是什么意思?其实我也很不想说穿它……由于输出结果不同的程序有无穷多种,最简的程序代码显然也有无穷多个;但长度不超过N的代码只有有限多个,因此必然存在长度大于N的最简代码。
再补充一下:有人问到,B程序如何模拟运行一段别的代码?这个问题问的好!事实上,一个程序语言是可以自我解释的;换句话说,你完全可以写出一个C语言解释器,而它本身就是用C语言来写的。因此,B程序能够“运行”其它代码,并保证跟它的输出结果一样(即使输出结果有无穷多)。显然,即使这样停机问题仍然没有解决,因为你能模拟它运行了也不知道它会不会停机。
“自我解释”听起来很不可思议,但事实上是千真万确的。C语言的自我解释器我不知道有没有,不过用JavaScript写的JavaScript引擎倒是有一个。你甚至能瞻仰到它的源码。
补充3:还有人问到,既然输入也要算进代码长度,那会不会出现纯粹的代码长度没超过N,但把N一输进去代码长度就超过N了?其实,当N取到一定大时,纯代码长度加输入长度必然会超过N,因为数字N本身的长度是以log(n)的级别增长的,总有某个时候会有纯代码长度+log(N)<N。
参考资料:http://www.flownet.com/gat/chaitin.html
Chaitin定理指出,上述问题是一个不可解问题,再牛的人也不可能编写出这样的程序。证明方式与大多数此类问题一样,都是采用反证加构造的方法证明的。你能想到这个证明方法吗?
假设我们有一个程序A,该程序能读入一段代码并且判断该代码是否最简。写一个程序B,该程序读入一个自然数N,然后枚举出所有长度大于N的程序代码并用程序A进行检测,直到找到一个最简的代码;然后运行这个最简代码,输出和这个最简代码一样的输出内容。现在,运行程序B,输入一个比程序B的代码长度更大的数,让程序B去找一个比它自身更长的最简代码。但是,程序B比这个最简代码要短,输出内容却和它相同,于是矛盾就产生了。
但是,有没有可能程序B没有输出呢?换句话说,程序B会不会根本找不到一个比它长的最简代码呢?当然不会,因为最简代码显然有无穷多个。
补充一下:有人没明白这里“最简代码有无穷多个”是什么意思?其实我也很不想说穿它……由于输出结果不同的程序有无穷多种,最简的程序代码显然也有无穷多个;但长度不超过N的代码只有有限多个,因此必然存在长度大于N的最简代码。
再补充一下:有人问到,B程序如何模拟运行一段别的代码?这个问题问的好!事实上,一个程序语言是可以自我解释的;换句话说,你完全可以写出一个C语言解释器,而它本身就是用C语言来写的。因此,B程序能够“运行”其它代码,并保证跟它的输出结果一样(即使输出结果有无穷多)。显然,即使这样停机问题仍然没有解决,因为你能模拟它运行了也不知道它会不会停机。
“自我解释”听起来很不可思议,但事实上是千真万确的。C语言的自我解释器我不知道有没有,不过用JavaScript写的JavaScript引擎倒是有一个。你甚至能瞻仰到它的源码。
补充3:还有人问到,既然输入也要算进代码长度,那会不会出现纯粹的代码长度没超过N,但把N一输进去代码长度就超过N了?其实,当N取到一定大时,纯代码长度加输入长度必然会超过N,因为数字N本身的长度是以log(n)的级别增长的,总有某个时候会有纯代码长度+log(N)<N。
参考资料:http://www.flownet.com/gat/chaitin.html
相关文章推荐
- C语言-判断一个数是否为素数-经典代码-编程
- 编程经典书籍推荐:重构 改善既有代码的设计
- 7.微软亚院之编程判断俩个链表是否相交(如果链表可能有环)
- Android 中 Handler 引起的内存泄露 在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用。其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何
- 编程之美-编程判断两个链表(可能含环)是否相交以及相交的第一个结点
- 经典证明:Cantor-Bernstein-Schroeder定理
- 经典证明:一个数论定理的组合学证明
- 经典的初学编程代码,有注释。
- 求一段字符串中元音字母的个数-C语言经典代码-编程
- 2017网易内推编程题(判断单词):解答代码
- js判断ie方法集锦(含正则)代码短小经典 原创
- 利用JavaScript和正则表达式进行丰富的日期判断(给其它项目组的代码,有比较好的编程风格和注释)
- 去掉一段字符串中的空格,以#结束-C语言经典代码-编程
- 黑马程序员java基础网络编程必须掌握的经典代码
- 【编程珠玑】代码优化的27条经典法则
- js判断ie方法集锦(含正则)代码短小经典 原创
- 编程 判断 是否满足条件 的 验证代码。
- Catalan(卡特兰)数及定理的简要证明------附上简要代码
- 【编程珠玑】代码优化的27条经典法则
- 不依赖于HECI驱动,如何判断客户机是否可能支持Intel AMT的参考代码