【问题标题】:Genetic algorithms: How to do crossover on ordered collections of unique elements?遗传算法:如何对独特元素的有序集合进行交叉?
【发布时间】:2016-06-22 00:50:35
【问题描述】:

此问题基于another one

我们如何有效地对由唯一元素的有序集合形成的染色体进行交叉操作?

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

【问题讨论】:

  • “已订购”是什么意思?第一个 {'a','b','c','d'} 似乎是按升序排列的,但是给出 {'e','f','a','b 的顺序是什么? '}?
  • 有序集合是指对顺序很重要的项目集合——例如 {'a', 'b', 'c', 'd'} 不同于 {'d', ' c','b','a'}。可以将其视为 Python 字典,其中 order 是基因编号,例如 {'gene#1':'a', 'gene#2':'b', 'gene#3':'c', 'gene#4':'d'}

标签: algorithm genetic-algorithm evolutionary-algorithm crossover


【解决方案1】:

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

然后只需将第一个父级的前 n 个元素放入子级,然后是来自第二个父级的其余长度-n 个元素。

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

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

还涉及“交叉概率”,基本上是 0 到 1 之间的随机数,这表明父母是否有孩子。如果他们不能生育,则返回两者中最好的。

【讨论】:

    【解决方案2】:

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

    一般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])
    

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

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

    (不确定是不是你的情况)

    【讨论】:

      【解决方案3】:

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

      但是,那它是一种遗传算法,不管你做错了什么,它无论如何都会消失,所以你不必担心保持某种强制的纯洁性。无论如何,它只会解决适应度函数的改进。

      【讨论】:

        猜你喜欢
        • 2019-08-19
        • 2011-05-25
        • 2014-08-12
        • 1970-01-01
        • 2019-01-12
        • 2016-08-31
        • 2015-06-29
        • 2015-07-03
        相关资源
        最近更新 更多