问题描述
我正在为 OneMax 算法做一个项目,但遇到了交叉问题。
在整个迭代过程中,我采用人员的最高“部门”并循环遍历
对于偶数,我分配了 5 个奇数人,他们将与他们交叉(即 0、4、8、12 和 16 都与 1、2、3、5、7 和 9 匹配,然后与 2、6、10 匹配, 14,18 都与 11,13,15,17,19 匹配)。这是为了确保没有重复。
然后我选择一个随机交叉点并拆分列表,然后将列表拆分并作为父 A 和 B 的 2 个拆分列表返回,然后可用于创建子 A 和 B。
我的问题是经过几次迭代后,总体收敛到完全相同的位串。
任何帮助将不胜感激!
代码:
交叉
def crossover(top20):
end = len(top20) - 1
newPop = []
# Person A crosses over with a list of 5 people
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,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
编辑:另一件事是它总是停在一个数字上,例如恰好在 hundrets 中。就像它会停在恰好 16.00 的平均值,并且所选顶部的总和正好是 8000
解决方法
这是我使用 3 种方法解决 OneMax 问题的最终产品,一种是常规的最大问题(即尝试获得所有 1),2 是进化到目标字符串,3 是欺骗性景观。它可以在此 gist
中找到