我已经成功地使用遗传算法进行了相当多的工作,但到目前为止忽略了遗传编程。据我所知,大多数程序仍然是由程序员编写的,我很好奇是什么阻碍了遗传编程的发展?
我想到了一些可能的解释:
- 搜索空间太大了,在噪声中找到有用的程序很困难。
- 大多数实际应用程序无法提供足够的数据来评估这样的空间。
- 很难将许多实际应用的有效性归纳为单一的适应度度量。换句话说,编写合适的适应度函数可能需要与编写实际程序相同的工作量。
你有任何想法吗?
我已经成功地使用遗传算法进行了相当多的工作,但到目前为止忽略了遗传编程。据我所知,大多数程序仍然是由程序员编写的,我很好奇是什么阻碍了遗传编程的发展?
我想到了一些可能的解释:
你有任何想法吗?
我在自己的研究中一直在考虑这个问题,我想说有很多原因:
GP领域中绝大部分研究都集中在生成公式上,而不是大多数程序员所生成的软件类型。该领域有很多计算机科学家,但很少有人专注于生成预期的程序类型,因此在该领域的进展缓慢。
过于强调使用LISP,因为它可以生成易于操作的树形结构,而不幸的是命令式程序被忽视了,因为它们涉及解决一些棘手的问题。要让程序员认真对待GP,它必须生成命令式程序。
真实程序包含循环结构,但循环在GP中难以实现,需要采用各种丑陋的约束条件以防止无限循环。
遗传编程不具有可扩展性。对于小问题和较小的可用语言来说,它很好,但正如您在第一点中提到的,搜索空间很快变得太大。
与人类程序员相比,GP可能会非常慢。但它非常可并行化,因此随着大量处理器核心成为常态,它很可能会获得实质性的好处。
另一个有效的答案是很难相信代码已经自动生成。这是正确的,但实际上我怀疑这并没有太大的影响,因为GP一开始就无法生成正确的程序类型。
strcmp
?你的算法可能会发现你的通过/失败测试用例长度的数学模式。如果你亲自尝试一下,你会发现遗传编程是最终的横向思维:你的程序倾向于以你没有想到的每种方式解决问题,其中大部分都出乎意料,(对于严肃的应用)可能是无用的。有一个著名案例试图使用基本电子元件进化振荡器。它根据电路的简单性和输出的振荡来评估。它产生了如此简单的东西,研究人员确信它不可能工作,但它确实起作用:它正在从环境中接收和放大无线电波。
编辑引用:
Graham-Rowe,Duncan。 “Radio emerges from the electronic soup。”《New Scientist》,vol.175,no.2358,p.19(2002年8月31日)。可在http://www.newscientist.com/news/news.jsp?id=ns99992732上在线获取。
然而,该链接现在似乎已经损坏了。
新链接是http://www.newscientist.com/article/dn2732-radio-emerges-from-the-electronic-soup.html
我知道我来晚了,但我想指出几点。我非常幸运地与John Koza合作他的《遗传编程4》书。
我们大多数人日常工作中所做的编程——连接GUI事件、推动像素、数据库等等——绝对不是GP旨在构建的类型。
John Koza用他的一百台机器群(如果我没记错的话!)寻找有趣问题的解决方案(想想NP难度)。可悲的是,我们程序员每天处理的大多数问题都不是很有趣或困难的问题,大多数只是令人恼怒和耗费时间的问题。
Ben Jackson关于基因工程电子振荡器的说法是这个主题中最接近Dr. Koza和团队实际工作的事情。GP系列书中有许多电路的例子。
Tom Castle在这里提到的命令式程序并不完全正确。 John和公司的开创性例子是天线设计。它几乎是一个三维绘图程序,具有诸如LOGO绘图语言的命令,用于设计天线。它有moveto、lineto类型的命令,用于在栈上推送和弹出矩阵。我上周看过的GP软件包jgap直接支持:一个可以包含void返回语句的容器类型非终端,然后在结尾有一个返回语句。我相信它甚至有类似本地变量的东西,虽然我没有仔细看。
早期GP运行围绕的原始LISP设计有时确实很痛苦,这当然是真的。将GP运行的输出转换为更可用代码的任务可能是一种成年礼。
简而言之:GP实际上并不是自动编程系统。它是自动发明系统。
这是因为它已被证明在理论上是不可能的(至少对于正确的程序)。
假设您拥有无限的计算能力,放弃搜索空间大小、速度等其他“速度”问题。现在只面临两个问题: - 生成的程序是否会停止? - 如何确保生成的程序按照我想要的方式运行?
第一个问题是可计算性理论中的一个核心问题,被称为停机问题。图灵在1936年证明了该问题对于所有程序输入对都是不可判定的。 这意味着在某些情况下可能是可以实现的,但并非所有情况都可以。没有自动化过程可以确定程序是否停止。 对于这个问题,您无能为力;)
与程序正确性相关的第二个问题。在遗传编程中,通常通过示例值进行验证,这根本不构成任何正确性证明。 这类似于单元测试,只对一些示例给出正确结果,但是不能提供一般的证明。例如,如果我编写一个素数检查器,并仅使用3、5、7和11进行测试,则对于每个奇数返回true的程序将通过测试。
进一步的做法是使用自动化证明。算法正确性的自动化证明实际上与数学自动定理证明密切相关。您可以使用公理化系统描述程序,并尝试自动证明语句的正确性。三件事情:
原始汤看起来可疑又不可口。在我的生产代码里,我更喜欢智能设计。