遗传算法:如何在有序的独特元素集合上进行交叉?

时间:2016-03-08 07:13:59

标签: algorithm genetic-algorithm evolutionary-algorithm crossover

此问题建立在another one上。

我们怎样才能有效地在由有序的独特元素集合形成的染色体上实现交叉操作?

两个这样的父染色体是{'a','b','c','d'}{'e','f','a','b'};父母的两个可能的子染色体是{'e','f','c','d'}{'a','f','c','b'}

3 个答案:

答案 0 :(得分:1)

是。这是一个跨越。去做。假设元素在同一个地方,只要你通过选择一个点进行交叉,然后将数组交换到该点以外,你就不会复制元素。

但是,那么它是一种遗传算法,如果你做了一些有问题的东西并不重要它无论如何都应该消亡,所以你不必担心保持某种强制纯度。无论如何,它只会解决健身功能的改进。

答案 1 :(得分:0)

你可以尝试一种统一的交叉。

一般来说,Uniform Crossover使用两个父母之间的固定混合比率,并且操作员评估父染色体中的每个基因,以0.5的概率进行交换。

使用Python语法:

import random

p = [['a','b','c','d'], ['e','f','a','b']]    # parents

for i in range(len(p[0])):
   offspring.append(p[random.randint(0, 1)][i])

Uniform Crossover

鉴于唯一性约束,必须修改基本方案:

import random

p = [['a','b','c','d'], ['e','f','a','b']]    # parents

for i in range(len(p[0])):
    if p[1][i] in p[0]:    # cannot risk crossover, keep basic gene
        offspring.append(p[0][i])
    else:                  # standard uniform crossover
        offspring.append(p[random.randint(0, 1)][i])

“自动”满足约束条件,您有较小的搜索空间

请注意,交叉在某种程度上与第一个父级(p[0])绑定,我们得到的变体数量有限:

CHROMOSOME FREQUENCY
abcd       *************************
efcd       ************************
ebcd       ************************
afcd       ************************

在这方面,一个小改进是:

if p[1][i] in offspring or p[1][i] in p[0][i:]:
    offspring.append(p[0][i])
else:
    offspring.append(p[random.randint(0, 1)][i])

CHROMOSOME FREQUENCY
efcd       ******
afcd       ************
efad       ******
ebcd       ************
efcb       ******
efab       ******
ebad       ************
abcd       *************************
afcb       ************

但“诀窍”仅适用于一些父母。例如。转换父母:

p = [['e','f','a','b'], ['a','b','c','d']]

你又来了:

CHROMOSOME FREQUENCY
efcd       *************************
efcb       ************************
efad       *************************
efab       ************************

edge recombination operator是另一种可能性:

  

ERO通过查看边缘而不是顶点来创建类似于一组现有路径(父项)的路径。当需要具有非重复基因序列​​的基因型时,例如对于旅行商问题,其主要应用是遗传算法中的交叉。

(不确定是你的情况)

答案 2 :(得分:0)

最简单的解决方案是选择0和父母之间的随机索引。长度。让我们给索引n命名。

然后将第一个父元素的前n个元素放在子元素中,然后是第二个父元素中的其余长度为n个元素。

看看我如何在这里实现交叉方法:

https://github.com/amihaiemil/eva/blob/master/src/main/java/com/amihaiemil/eva/util/BinaryArraySolution.java

还有一个"交叉概率"所涉及的基本上是0到1之间的随机,这决定了父母是否有孩子。如果他们不能生孩子,那么返回2中最好的。