遗传程序设计


13

最近,我在浏览Reddit时遇到了一个链接到“ JavaScript遗传算法”示例的帖子。我对遗传算法和编程的概念非常着迷,但是即使经过了谷歌搜索,我仍然感到有些困惑。它是如何工作的?

我想这些词汇对我来说比什么都使我更困惑。我希望能看到一些简短的例子,也许还有一些解释。只是基因编程的概念以及我如何在项目中实现它,为什么?


1
马特·巴克兰(Mat Buckland)有一本名为《游戏编程的AI技术》的好书(amazon.com/Techniques-Programming-Premier-Press-Develop/dp/…),其中一半涵盖了遗传算法。这本书的书名有点用词不当,是一本关于GA和神经网络的书。这是该主题的精彩介绍。
史蒂文·埃弗斯

Answers:


19

听起来您在谈论遗传算法,而不是在谈论遗传编程,但这是我对您的理解的贡献。


从GA的组成部分考虑GA可能很方便。

因此,假设您遇到某种问题。您需要的第一件事是表达解决方案外观的方法。如果您遇到城市A,B,C,D,E 的旅行推销员问题,那么您已经知道解决方案是什么样的,即城市名称的数组[B,C,A,D,E]。

这就是基因

否则称为解决问题的潜在方法。就像史蒂文·A·劳(Steven A. Lowe)提到的那样,位串是编码基因的常用方法,但这不是必需的。它只是使某些事情变得容易。重要的部分是您可以用一种类似于数组的方式表示解决方案。

现在。您怎么知道解决方案是否有效?您需要一个可以告诉您并为解决方案评分的功能。因此,对于TSP,您可能还具有使用路径[B,C,A,D,E]测量行进距离的功能。您指定的“等级”可能只是行进的距离,但在更复杂的问题中,您可能会包括旅行成本和其他事项。

这是健身功能

因此,现在您可以采用潜在的解决方案,并找出是否有什么好处。下一步是什么?

接下来,我们需要开始我们的第一代。因此,我们生成了一堆随机解。他们是否好没关系。这是您的初始人口或种子人口。您可以将其称为您的基因库。

因此,您需要使用最初的基因库,然后将适应度函数应用于所有这些对象,并为其评分。现在,您需要容纳其中两个,并从中获得新的人口-下一代。您选择谁?好吧,您不想只选择适合的最适合者,这可能会导致一些问题。相反,您需要选择功能

一种易于观察的选择方法是使用一种转盘:每个基因都是转盘上的一个切片,其适应性得分表明其切片的大小(适应性越好,切片越大)。放置一个指向车轮的销钉并旋转一下(即生成一个随机数)。别针指向第一个父对象。再为第二个父母做。

现在,您需要创建新的子代。您想合并父母以产生新的人口。有多种方法可以做到这一点,但是它们都被称为交叉功能。您可以将它们分成两半,在父母之间交换两半,或者进行某种交织。这与哺育新子女的哺乳动物父母非常相似->他们都向新子女贡献自己的基因。

有了新一代后,您就会对每个孩子进行随机但罕见的突变。我经常看到突变发生率不到1%。该突变功能会随机改变你的编码基因的东西。如果您的基因是一个字符串,它可能会交换一点,如果它是一个城市数组,则可能会交换列表中的2个城市。重要的是,这是相对罕见的事件,并且会混杂在一起。

重复此过程,直到达到所需的世代数,或者直到您的健身功能使父母的健身得分一直保持较高,并且您找到了一个最佳的解决方案(希望您做对了)。


这有点罗word,所以让我用一个隐喻来总结一下:

  1. 基因就是人:人解决问题
  2. 健身功能是等级:人们根据解决问题的能力来获得等级
  3. 您选择2个人来繁殖新的种群:您为成绩较好的人提供更好的繁殖机会
  4. 当父母繁殖时,他们结合起来产生孩子。
  5. 你很少随机地变异他们的孩子
  6. 您给新人群的孩子评分
  7. 冲洗并重复

希望这可以帮助。


这是一个很好的解释。我一直以为遗传算法可以更好地描述为达尔文算法或进化算法,但是“遗传”确实可以更好地描述机械原理(如果不是整体思想的话)。我称它们为达尔文遗传算法。
史蒂文·卢

康韦的人生游戏是遗传算法吗?
Florian Margaine 2014年

@Florian Margaine:生命游戏是细胞自动机,一个不相关的概念(从生命游戏完全是确定性的事实出发,而遗传算法是随机的)。
scrwtp 2014年

1
毫无疑问,这是我所听过的关于GA的唯一最好的解释。我见过过去多次提到过的遗传算法,通常是随手移植,但直到现在才真正了解它们。谢谢!
洛克

我希望我第一次学习GA时能看到这种解释!
Avrohom Yisroel

7

将问题的解决方案编码为位字符串

编写一个函数(称为“适应性”函数)以评估编码后的解决方案的位字符串的“良好”程度-结果通常为0到1之间的数字

随机生成一堆这些位串并评估其适合度

选择一堆(通常是更适合的一堆),将其切成两半,交换成两半,以制作一些新的比特串(交叉)

然后有时候,在一些新的位字符串中随机翻转一些位(突变)

重复进行,直到找到一个好的解决方案

为什么这样做:某些问题具有巨大的可能解决方案空间,太大了,以至于无法评估所有可能性(请参阅旅行商问题)

我强烈推荐《搜索,优化和机器学习中的遗传算法》一书


在亚马逊上搜索“遗传算法”后,我得到了四页的东西。我只看了第一页,但那里没有一本书标题为“遗传算法”。您能否提供这本书的更多详细信息,例如完整标题和作者?
David Thornley

挑战:将答案作为遗传算法重述。[-:
非常愚蠢,2011年

@David链接已添加;出版于1989年,所以现在可能会有更好的出版,但是这一本书很好地说明了问题
Steven A. Lowe

1
@veryfoolish:首先,将问题重新陈述为有界离散空间解决方案
Steven A. Lowe

@David遗传算法也可能是一本有关人工智能的大书中的一两章。
巴里·布朗

6

基因编程是让计算机为您编写程序的一种方式!

不要认为像MS Word这样的“程序”,而应将“程序”视为以下内容:

function(x){ return x*2; }

此功能(或程序)本身没有理由存在。我们正在寻找问题的解决方案。如果您需要找到两个数字的和,则只需打开计算器并进行数学运算即可。如果什么人给你下面的表格,并要求你找出之间的关系result,并xy

x   y   result
99  1   (3.02)
79  88   2.01 
21  62   5.01 
84  52  (6.58)
12  70   5.54 
67  18   0.73 

此数据是您的“培训”数据。您的计算机将使用此数据生成一些假设,然后将其与实际数据进行比较。

假设您不了解统计信息,并认为很难独自解决此问题,那么计算机将为您解决。

让计算机随机产生疯狂的猜测

您让计算机生成一百万个答案,然后看是否有任何答案(猜测...一百万次!)。以下是一些猜测的示例:

function(x,y){ return x+y; } // wrong
function(x,y){ return x/1*1*1*1*1*1+y; } //wrong, silly

您可能知道也可能不知道,但是功能或程序也可以表示为树,例如,第二个功能为:

(+ (/ x (* 1 (* 1 (* 1 (* 1 (* 1 1)))) y)

通过像这样缩进,可以使它看起来更像一棵树(顺便说一句,查找反向修饰符号和lisp语法...但是您很快就会理解为什么我们代表这样的程序):

(+ 
    (/ x 
        (* 1 
            (* 1 
                (* 1 
                    (* 1 
                        (* 1 1)))) 
    y)

+是有两个的“叶子”顶部/y/本身有几个孩子等)

这就是为什么您对遗传编程中的“树”有如此多的了解的原因。在任何情况下,我们插上的价值观xy这个功能,它为我们提供了错误的答案。不过这并不奇怪,因为我们是随机生成的。

您现在决定生成一百万个这样的解决方案。他们都是错的。但是,您注意到某些答案比其他答案更接近正确答案。换句话说,某些解决方案比其他解决方案更“适合”。请注意,计算机不知道什么是“正确”和“错误”,因此您必须提供自己的“健身功能”。该功能将提供潜在的解决方案,培训数据,并负责告诉GP系统该解决方案的“适用性”。可以想象,此函数运行数百万次。

是什么让GP与众不同

这就是使基因编程与狂野猜测不同的原因。您决定再进行一轮猜测。但是,您可以更智能地进行操作。您将前10%的猜测(接近实际值的猜测)作为第二代的一部分。您还可以采用许多这样的解决方案(也许是10%的比例...我不记得了),然后决定“混合使用”。

您随机选择两个解决方案,随机选择子树并开始交换它们。因此,解决方案A的一部分最终落在解决方案B之下,反之亦然-您只需“交叉”它们即可。您还可以采用一些解决方案,然后简单地对其进行“变异” ...采用一些子树并将其“拧紧”(嘿,如果解决方案很糟糕,“无缘无故地耕种”实际上可能会改善它)。

对此有一个好的思考方式:您的父母有某些属性-头发的颜色,身高,患病的可能性等。作为孩子,您从父母双方那里继承了不同的属性。如果您的父母都是奥运会运动员,那么您也将成为超级运动员,对吗?好吧,生物学家,社会学家甚至历史学家可能会对这个想法持怀疑态度,但是计算机科学家并不关心优生学的道德。他们只是看到一个“系统”在提供解决方案方面做得很好,因此他们决定在软件中对其进行建模。

如果它实际上与生物学不匹配,但仍能提供良好的答案,那么……许多计算机科学家会集体说:“不管怎么说,谢谢您的术语。” 另请注意,您的所有兄弟姐妹并不一定完全一样……即使他们的父母相同。每个人都有因任何原因而变异的基因(请不要向生物学家展示,这是要了解许多术语背后的动机)。

因此,现在我们正在使计算机生成数百万个程序并测量其适用性。最好的解决方案可以存入下一代。我们还对“种群”进行“变异”和交叉(注意如何使用遗传学和生物学的语言)。创建第二代后,将再次测量适合度。由于这一代人拥有上一代人的最佳解决方案,并且我们越过了最好的解决方案并对其进行了变异(以及中等水平的人口-以保持多样性),因此这一代人至少应比上一代人好一点。

我们将这一代延续了很多代。每一代(希望如此)都会提供越来越好的解决方案,直到我们得到正确的答案。例如:

(+ (- 2.2 (/ x 11) (* 7 (cos y))))

好看看,这是正确的!
(我从http://en.wikipedia.org/wiki/Genetic_programming复制了此文件,该文件也对此树做了图形表示)

什物

这里有一些重要的问题,例如如何确定+, -, *, /, cos, sin, tanGP系统可以使用哪些“端子”(),如何编写适应度函数以及系统如何处理非感性程序,例如(1 + cos)(2 / "hello")(以及其他)。

发展方程式很无聊。如果您的终端机看起来像以下内容,它将变得更加有趣:(开火,感知敌人,移动,...)并且您的健身功能可以衡量您的健康状况以及武术怪物的尸体数量。

我大部分是从内存中写的,但这是基本思想。我上大学时曾做过GP。您绝对应该玩弄它。不必担心了解所有术语,只需下载一些免费的GP系统,通过几个示例进行操作,即可体会到它,并编写自己的有趣示例(查找不同数据集之间的关系,尝试将其连接到游戏中) API等)


1

适者生存:Windows窗体的自然选择是我入门遗传编程的方法。易于阅读,提供可供下载的代码。不利的一面是GP需要一种方法来执行在运行时创建的代码,而在撰写本文时,C#不太适合此任务。这就是该示例在运行时使用CodeDOM生成,编译和运行代码的原因,这本身为其添加了另一层复杂性。

从那时起,情况发生了变化,.NET现在拥有自己的ExpressionTree API,与本文中介绍的方法相比,它可能允许在C#中使用更优雅的GP实现。但这足以了解GP的工作原理。

在这里,您可以下载有关GP的免费电子书,其中还包括一个非常简短的Java代码示例,您可能也会觉得很有趣。


-1

遗传算法和遗传编程是相关的,但是概念不同。

遗传算法(GA)是用于复杂优化问题的搜索算法。在GA中,您可以在“ DNA”位串中编码某个问题的解决方案的参数,然后随机“繁殖”这些位串:通过组合部分位来再现它们,并通过删除所有位串来应用“适者生存”除了那些最能解决您问题的方法之外,您还可以获得其他方法。

基因编程(GP)更加复杂:在这里,您不是用程序的DNA(位串)来表示程序,而是通过解析您选择和繁殖的树来表示程序。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.