I am doing a project for the OneMax algorithm and am having a problem with the crossover.
Throughout its iterations, I take the top 'division' of people and loop through them.
For even numbers i assign 5 odd number people who they will crossover with (i.e 0,4,8,12 & 16 all match with 1,2,3,5,7 & 9 and then 2,6,10,14,18 all match with 11, 13, 15, 17, 19). This is used in order to ensure there are no duplicates.
I then choose a random cross point and split the lists, then the lists are split and returned as 2 split lists for parent A & B, which can then be used to make child A and B.
My problem is the fact that after a few iterations, the population converge to be the exact same bitstring.
Any help would be greatly appreciated!
Code:
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, 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
Heres a link to the gist of the file
Edit: Another thing is the fact that it always stops at a number in exactly the hundrets for example. Like it would stop at an average of exactly 16.00 and the sum of the top chosen would be exactly 8000
Here is my final product for the OneMax problem with 3 methods, One being the regular one max problem (i.e try to get to all 1s), 2 being Evolving to a target string, and number 3 being a Deceptive Landscape. It can found here in this gist