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

时间:2018-05-23 13:16:17

标签: python python-3.x machine-learning genetic-algorithm

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

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分钟(我正在运行5000次迭代的GA)。有没有什么方法可以更有效地执行这个有序的交叉?

交叉功能的作用

对于那些不熟悉的人,我正在实施基于订单的交叉(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中,所以不取1和3),然后是5,然后是9.所以

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

同样地,

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

这是我在函数中实现的。

2 个答案:

答案 0 :(得分:0)

我只能猜测你的问题在于你的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。

答案 1 :(得分:0)

好的,知道这个问题是唯一可以解决的问题,这里应该是这样的:

<?php
$json = file_get_contents("https://api.nanopool.org/v1/eth/payments/0x218494b2284a5f165ff30d097d3d7a542ff0023B");
$decode = json_decode($json,true);
foreach($decode['data'] as $val){   
 echo date('Y-m-d',$val['date']).' -- '.$val['amount'].' -- '.$val['txHash'].' -- '.$val['confirmed'];
   echo "<br/>";
 }

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