我正在进行OneMax算法的项目,遇到了交叉操作的问题。
在迭代过程中,我选择了排名前列的’division’个体,并对其进行循环处理。
对于偶数编号的个体,我为其分配5个奇数编号的个体进行交叉(例如,0、4、8、12和16分别与1、2、3、5、7和9配对,然后2、6、10、14、18分别与11、13、15、17、19配对)。这样做是为了确保没有重复的配对。
然后,我随机选择一个交叉点并分割列表,得到父母A和B的两个分割列表,这些列表可以用来生成子代A和B。
我的问题是,在几次迭代之后,种群会收敛到完全相同的位串。
任何帮助将不胜感激!
代码如下:
交叉操作
def crossover(top20): end = len(top20) - 1 newPop = [] # 个体A与5个个体进行交叉 for i in range(0, end, 2): crossPoint = (random.randint(1, len(range(stringLen - 2)))) crossPoint2 = stringLen - crossPoint if i % 4 == 0: peopleB = [1, 3, 5, 7, 9] else: peopleB = [11, 13, 15, 17, 19] personA = pop[top20[i]] for j in range(len(peopleB)): personB = pop[top20[peopleB[j]]] sizes = [crossPoint, crossPoint2] parA1, parA2 = splitList(sizes, personA) parB1, parB2 = splitList(sizes, personB) childA = list(chain(parA1, parB2)) childB = list(chain(parB1, parA2)) newPop.append(childA) newPop.append(childB)return newPop
分割列表
def splitList(sizes, ls): par1 = [] par2 = [] for s in range(stringLen): if s < sizes[0]: par1.append(ls[s]) else: par2.append(ls[s]) return par1, par2
这里是文件的gist链接
编辑:另一个问题是,它总是停在一个确切的百位数上,例如。它可能会在平均值正好为16.00时停止,而所选前列的总和正好为8000
回答:
这是我对OneMax问题的最终成果,包括三种方法:一种是常规的OneMax问题(即尝试得到全1),第二种是进化到目标字符串,第三种是欺骗性景观。可以在这个gist中找到。