Python Deap library, how to access initRepeat mapp

2019-08-21 10:45发布

问题:

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