Я реализовал генетический алгоритм в 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 минут (я бегу 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
Это то, что я реализую в функции.