Here's my code where I am flipping a bit, crossing over two lists and selecting random elements of lists:
def selRandom(individuals, k):
return [random.choice(individuals) for i in range(k)]
def cxOnePoint(ind1, ind2):
size = min(len(ind1), len(ind2))
cxpoint = random.randint(1, size - 1)
ind1[cxpoint:], ind2[cxpoint:] = ind2[cxpoint:], ind1[cxpoint:]
return ind1, ind2
def mutFlipBit(individual, indpb):
for i in range(len(individual)):
if random.random() < indpb:
individual[i] = type(individual[i])(not individual[i])
return individual,
def operators(selection, crossover, mutation, parent, k, indvpb):
select = ['randomSelection']
cx = ['OnePoint']
mutate = ['flipBitMutate']
if selection not in select:
return "invalid"
else:
if selection == 'randomSelection':
(parent) = selRandom(parent, k)
if crossover not in cx:
return "invalid"
else:
if crossover == 'OnePoint':
ind = cxOnePoint(parent[0], parent[1])
if mutation not in mutate:
return "not valid"
else:
if mutation == 'flipBitMutate':
mutatedIndvidual = mutFlipBit(ind[0], indvpb)
return parent, ind, mutatedIndvidual
I run this to execute the code:
indv = ([1,0,1,0,1,0,1,1],[0,1,0,1,0,0,0,1],[0,0,1,1,1,1,0,0],[0,1,1,1,0,0,0,1],[1,0,0,0,1,1,1,1])
selection = 'randomSelection'
crossover = 'OnePoint'
mutation = 'flipBitMutate'
selected_parent, ind, mutatedIndvidual = operators(selection = selection , crossover = crossover, mutation = mutation, parent = indv, k = 3, indvpb = 0.1 )
print("Parents:\n",indv)
print("Selected parent to reproduce:\n",selected_parent)
print("Crossover offsprings:\n",ind)
print("Mutated offsprings",mutatedIndvidual)
And get the result:
Parents:
([1, 0, 1, 0, 1, 0, 1, 1], [1, 1, 1, 1, 0, 0, 1, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 1, 0, 1, 0, 0, 0, 1], [1, 0, 0, 0, 1, 1, 1, 1])
Selected parent to reproduce:
[[1, 1, 1, 1, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0, 0, 1], [1, 1, 1, 1, 0, 0, 1, 0]]
Crossover offsprings:
([1, 1, 1, 1, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0, 0, 1])
Mutated offsprings ([1, 1, 1, 1, 0, 0, 1, 0],)
So the code is executing but is not functioning. It randomely selects from the tuple and then it does not crossovers (mixes the bits from two lists) or flips the bits. If I test run the code separately (out of the operator method) it works:
a = [1,1,1,1,1,1,1,1]
b = [0,0,0,0,0,0,0,0]
c = [1,0,0,0,1,1,0,1]
d= (a,b,c)
print("selecting randomely:\n",selRandom(d,1))
print("TESTING CROSSOVER\n", cxOnePoint(a,b))
print("Mutate:\n",mutFlipBit(a,0.4))
and got the proper result:
selecting randomely:
[[0, 0, 0, 0, 0, 0, 0, 0]]
TESTING CROSSOVER
([1, 1, 1, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 1])
Mutate:
([0, 1, 1, 1, 1, 1, 1, 1],)
What is the logical mistake that I am making here?
Thank you!
To answer my own question:
I have assigned original lists in the mutFlipBit()
and cxOnePoint
and I changed my 'mutFlipBit()' to:
def mutation(individual, indp):
return [not ind if random.random() < indp else ind for ind in individual]
This worked for me