DEAP竞赛选择,避免重复个体的交叉

2024-05-03 08:04:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我继承了一段使用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

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


Tags: inforlenclonetoolboxzipselectmate