What I want my algorithm to do
I want to have a bunch of random words as individuals in my population, whos fitness is compared to an "optimal" word. If the length of the words are equivalent, that's +1 in fitness. For each char that is the same, that's also +1 in fitness, +1.1 if it is in the same index.
Unfortunately I'm having a really though time understanding deaps docs. This is what I have tried among other things so far.
Attempted Code
from deap import creator
from deap import tools
import random
import time
from create_random_string import get_random_word
ans = "hot"
creator.create("FitnessMax", base.Fitness, weights=(len(ans)+2,))
creator.create("Individual", str, fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("individual",tools.initRepeat,creator.Individual,get_random_word, n=1)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
def evalOneMax(individual):
fitness = 0
if(len(ans)==len(individual)):
fitness+=1
for i in range(0,len(ans)):
if(ans[i]==individual[i]):
fitness+=1.1
for i in range(0,len(ans)):
if individual.find(ans[i]) != -1:
fitness+=1
return (fitness,)
#----------
# Operator registration
#----------
# register the goal / fitness function
toolbox.register("evaluate", evalOneMax)
# register the crossover operator
toolbox.register("mate", tools.cxTwoPoint)
# register a mutation operator with a probability to
# flip each attribute/gene of 0.05
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
# operator for selecting individuals for breeding the next
# generation: each individual of the current generation
# is replaced by the 'fittest' (best) of three individuals
# drawn randomly from the current generation.
toolbox.register("select", tools.selTournament, tournsize=3)
#----------
if __name__== '__main__':
random.seed(64)
pop = toolbox.population(n=50)
# CXPB is the probability with which two individuals
# are crossed
#
# MUTPB is the probability for mutating an individual
CXPB, MUTPB = 0.5, 0.2
print("Start of evolution")
fitnesses = list(map(toolbox.evaluate, pop))
for ind, fit in zip(pop, fitnesses):
ind.fitness.values = fit
Explanation of Code(to the best of my understanding)
I first create a population that consists of my creator.Individual class mapped to a random word. I then pass this into my evaluation function to get each creator.Individual classes fitness. At this step I of course get an error because I'm not accessing the random word. My question is, how CAN I access this word?
Alternative
I have tried an alternative method where I just keep the word as a variable in the Individual class like so, but this really does not play well with the rest of deaps functions that I am using. With this method I get errors in the crossover operator deap gives me. I would rather not have to create my own crossover operator.
creator.create("FitnessMax", base.Fitness, weights=(len(ans),))
creator.create("Individual", str, fitness=creator.FitnessMax, word=get_random_word(True,0))
toolbox = base.Toolbox()
toolbox.register("individual",creator.Individual)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
EDIT
To be more specific, if I put a "print(individual)" line inside of my evalOneMax function it outputs
<generator object initRepeat.<locals>.<genexpr> at 0x1076ffe60>
How can I access both the random word that is mapped as well as the fitness of the individual