繁体   English   中英

遗传算法-Python中的有序交叉

[英]Genetic algorithm - ordered crossover in python

我已经在python 3中实现了遗传算法,并在代码审查中发布了一个问题,但没有答案,这主要是因为我的算法运行非常缓慢。 通过有选择地注释掉我代码的不同部分,我缩小了代码的这一部分(交叉算法)的瓶颈:

def crossover(self, mum, dad):
    """Implements ordered crossover"""

    size = len(mum.vertices)

    # Choose random start/end position for crossover
    alice, bob = [-1] * size, [-1] * size
    start, end = sorted([random.randrange(size) for _ in range(2)])

    # Replicate mum's sequence for alice, dad's sequence for bob
    for i in range(start, end + 1):
        alice[i] = mum.vertices[i]
        bob[i] = dad.vertices[i]

    # # Fill the remaining position with the other parents' entries
    # current_dad_position, current_mum_position = 0, 0
    #
    # for i in chain(range(start), range(end + 1, size)):
    #
    #     while dad.vertices[current_dad_position] in alice:
    #         current_dad_position += 1
    #
    #     while mum.vertices[current_mum_position] in bob:
    #         current_mum_position += 1
    #
    #     alice[i] = dad.vertices[current_dad_position]
    #     bob[i] = mum.vertices[current_mum_position]
    #
    # # Return twins
    # return graph.Tour(self.g, alice), graph.Tour(self.g, bob)
    return mum, dad

被注释掉的部分使我的程序运行时间从〜7秒变为5-6分钟(我正在运行GA的5000次迭代)。 有什么方法可以更有效地执行此有序交叉吗?


交叉功能的作用

对于那些不熟悉的人,我正在实现基于订单的交叉(OX2)。 给定两个连续整数数组(父级),则选择两个随机的开始/结束位置。

  mum   =   4   9   2   8   3   1   5   7   6
  dad   =   6   4   1   3   7   2   8   5   9
                    ^           ^
                  start        end

然后,两个孩子共享结果切片:

  child 1   =   _   _   2   8   3   1   _   _   _
  child 2   =   _   _   1   3   7   2   _   _   _
                        ^           ^

现在,只要避免重复,其余插槽将按照其他父项的出现顺序填充。 因此,由于孩子1的切片取自妈妈,因此其余条目均取自父亲。 首先我们取6,然后取4,然后我们取7(不取1和3,因为它们已经出现在妈妈的孩子1中),然后取5,然后取9。

  child 1   =   6   4   2   8   3   1   7   5   9

同样

  child 2   =   4   9   1   3   7   2   8   5   6

这就是我在函数中实现的。

我只能猜测您的问题在于以下事实:您的while循环和其中的增量不限于vertices矢量的实际大小,请设置硬限制并再次测试:

     while current_dad_position < size and dad.vertices[current_dad_position] in alice:
         current_dad_position += 1

     while current_mom_position < size and mum.vertices[current_mum_position] in bob:
         current_mum_position += 1

我不得不说这不一定会产生唯一的解决方案,因为我不知道如果没有足够的唯一唯一奇异顶点可供选择,那么算法将如何工作,因为它们违反了您的“而不是另一个”父母的限制。

对于任何对此进行测试的人,我建议您使用一个简单的示例输入来完成您的代码,而不要注释掉所讨论的代码,而应在注释中标记其BEGIN和END。

知道问题是建筑的唯一可解决的知识,这就是它的样子:

import random
import numpy as np

def crossover(mum, dad):
    """Implements ordered crossover"""

    size = len(mum.vertices)

    # Choose random start/end position for crossover
    alice, bob = [-1] * size, [-1] * size
    start, end = sorted([random.randrange(size) for _ in range(2)])

    # Replicate mum's sequence for alice, dad's sequence for bob
    alice_inherited = []
    bob_inherited = []
    for i in range(start, end + 1):
        alice[i] = mum.vertices[i]
        bob[i] = dad.vertices[i]
        alice_inherited.append(mum.vertices[i])
        bob_inherited.append(dad.vertices[i])

    print(alice, bob)
    #Fill the remaining position with the other parents' entries
    current_dad_position, current_mum_position = 0, 0

    fixed_pos = list(range(start, end + 1))       
    i = 0
    while i < size:
        if i in fixed_pos:
            i += 1
            continue

        test_alice = alice[i]
        if test_alice==-1: #to be filled
            dad_trait = dad.vertices[current_dad_position]
            while dad_trait in alice_inherited:
                current_dad_position += 1
                dad_trait = dad.vertices[current_dad_position]
            alice[i] = dad_trait
            alice_inherited.append(dad_trait)

        #repeat block for bob and mom
        i +=1

    return alice, bob

class Mum():
    def __init__(self):
        self.vertices =[  4,   9,   2,   8,   3,   1,   5,   7,   6 ]

class Dad():
    def __init__(self):
        self.vertices =  [ 6 ,  4  , 1  , 3 ,  7 ,  2  , 8  , 5 ,  9 ]

mum = Mum()  
dad = Dad()
a, b =  crossover(mum, dad) 
# a = [6, 4, 2, 8, 3, 1, 5, 7, 9]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM