首页 > 解决方案 > DEAP 锦标赛选择,避免重复个人的交叉

问题描述

我继承了一段使用 DEAP 的 Python 代码,通过锦标赛选择来管理交叉步骤:

#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

这至少让我们度过了“它不会崩溃”的阶段,但它在做我们想要的吗?

标签: pythongenetic-algorithmdeap

解决方案


推荐阅读