我继承了一段使用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
这至少让我们越过了“它不会崩溃”的阶段,但它做了我们想要的吗
目前没有回答
相关问题 更多 >
编程相关推荐