DEAP Турнир Выбор, избегая пересечений с дубликатами лиц - PullRequest
1 голос
/ 05 марта 2020

Я унаследовал часть кода Python, который использует DEAP, с выбором турнира для управления шагом кроссовера:

#Early in the code
toolbox.register("select", tools.selTournament, tournsize=tournsize)

#Then later...
popu = toolbox.select(popu, k=len(popu))
popu = [toolbox.clone(ind) for ind in popu]
    for child1, child2 in zip(popu[::2], popu[1::2]):
        toolbox.mate(child1, child2)
        del child1.fitness.values, child2.fitness.values

Мне кажется, что это не имеет защиты для человека, которого пересекают - над собой, и я хотел бы избежать этой возможности.

Концептуально, это достаточно просто, но я не уверен, как реализовать это в Python.

Возможное решение 1: (см. Обновление ниже)

popu = toolbox.select(popu, k=len(popu))
for ind in range(1, len(popu), 2):
     while popu[ind] == popu[ind-1]:
          popu[ind] = toolbox.select(popu, k=1)

popu = [toolbox.clone(ind) for ind in popu]
     for child1, child2 in zip(popu[::2], popu[1::2]):
          toolbox.mate(child1, child2)
          del child1.fitness.values, child2.fitness.values

* Если возможен повторный выбор дубликатов по одному, я думаю, что установка дедупликации до клонирования верна, но я не уверен на 100%.

Возможное решение 2, чуть более грубая сила:

popu = toolbox.select(popu, k=len(popu))
for ind in range(1, len(popu), 2):
     while popu[ind] == popu[ind-1]:
          popu[ind] = popu[random.randint(0,len(popu)-1)]

popu = [toolbox.clone(ind) for ind in popu]
     for child1, child2 in zip(popu[::2], popu[1::2]):
          toolbox.mate(child1, child2)
          del child1.fitness.values, child2.fitness.values

Должны ли работать один или оба из них (с учетом того, что повторный выбор происходит в нужном месте)?

ОБНОВЛЕНИЕ:

Возможное решение № 1 необходимо изменить. Так как toolbox.select возвращает список, отдельный элемент popu должен быть установлен как элемент списка, а не весь список, даже когда список имеет длину 1. Вероятно, проще показать решение, чем записывать его в проза ...

Пересмотренное возможное решение 1:

popu = toolbox.select(popu, k=len(popu))
for ind in range(1, len(popu), 2):
     while popu[ind] == popu[ind-1]:
          repopu = toolbox.select(popu, k=1)
          popu[ind] = repopu[0]

popu = [toolbox.clone(ind) for ind in popu]
     for child1, child2 in zip(popu[::2], popu[1::2]):
          toolbox.mate(child1, child2)
          del child1.fitness.values, child2.fitness.values

Это, по крайней мере, выводит нас из стадии «это не кр sh», но делает ли это то, что мы хотим ?

...