祝你好运。
当然,你可以编写一个“变异”程序,读取一个程序并随机添加、删除或更改一些字符。然后你可以编译结果,看看输出是否比原始程序更好。(不过我们如何定义和衡量“更好”还有待商榷。)当然,99.9%的时间结果会是编译错误:语法错误、未定义的变量等等。而且肯定大部分都是完全错误的。
试试一些非常简单的问题。比如,从一个读取两个数字、将它们相加并输出总和的程序开始。假设目标是一个读取三个数字并计算总和的程序。这样的程序的长度和复杂程度当然取决于语言。假设我们有一种非常高级的语言,只需要一行代码就可以读取或写入一个数字。那么起始程序只有4行:
read x
read y
total=x+y
write total
最简单的程序来达到预期目标可能是这样的:
read x
read y
read z
total=x+y+z
write total
因此,通过随机突变,我们必须添加“read z”和“+z”,总共9个字符,包括空格和换行符。让我们在突变程序上简化操作,假设它总是插入恰好9个随机字符,并且保证它们在正确的位置,并且从仅包含26个字母加上10个数字加上14个特殊字符的字符集中进行选择,即50个字符。那么它选出正确的9个字符的概率是多少?1/50^9 = 1/2.0e15。(好吧,如果它插入的是“read w”和“+w”而不是“read z”和“+z”,那么程序也可以正常工作,但我假设它会神奇地插入恰好正确数量的字符,并且总是将它们插入正确的位置,所以我认为这个估计仍然很慷慨。)
1/2.0e15是一个非常小的概率。即使程序每秒运行一千次,并且您可以快速测试输出,每秒的成功概率仍然只有1/2.0e12,每小时的成功概率为1/5.4e8,每天的成功概率为1/2.3e7。让它运行一年,成功的几率仍然只有1/62,000。
即使是一个适度有能力的程序员也应该能在10分钟内做出这样的改变吧?
请注意,更改必须至少以正确的“数据包”形式进行。也就是说,如果一个突变产生了“reax z”,那么它距离“read z”只有一个字符,但它仍然会产生编译错误,因此失败。
同样地,添加“read z”但将计算更改为“total=x+y+w”是行不通的。根据语言的不同,你要么会因为未定义的变量而得到错误,要么最好将其设为某个默认值,比如零,并给出不正确的结果。
我想,你可以理论上进行渐进式解决方案。也许一个突变添加了新的读取语句,然后将来的一个突变更新计算。但没有计算,额外的读取是毫无意义的。如何评估程序以确定额外的读取是否“朝着正确的方向迈出了一步”?我唯一看到的方法就是让一个智能实体在每次突变后阅读代码,并查看变化是否朝着期望的目标前进。如果你有一个能做到这一点的智能设计者,那么这意味着他知道期望的目标是什么以及如何实现它。此时,与其等待随机发生想要的变化,不如直接进行所需的更改会更有效率。
这是一个相当简单易懂的程序,使用一门非常容易的编程语言。大多数程序都是由几百行甚至几千行代码组成,而且所有代码都必须协同工作。任何随机过程能够写出一个可运行的程序的可能性都是微乎其微的。
也许有一些方法可以在某些非常专业的应用程序中实现类似此类的功能,其中您并不是真正进行随机变异,而是对解决方案的参数进行逐步修改。例如,我们有一个带有一些常量值的公式,但这些值我们不知道。我们知道在一些小型输入集上的正确结果。因此,我们随机更改常量,并且如果结果更接近正确答案,则从那里开始更改;否则,回到先前的值。但即使如此,我认为进行随机更改很少会产生有效结果。按照严格的公式尝试更改常量,例如从更改千位数开始,然后是百位数,十位数等等,可能会更有帮助。