Python DEAP library, using random words as individ

2019-09-05 11:31发布

问题:

I'm trying to get a better handle on DEAP. I want to make a genetic algorithm that has words as individuals as a population and it maximizes this by checking how far in distance(read: spelling) these words are from a given "maximal word". This is what I have done so far following examples in the documentation

import random
from randomwordgenerator import randomwordgenerator

from deap import base
from deap import creator
from deap import tools

creator.create("FitnessMax", base.Fitness, weights=("hot",))
creator.create("Individual", str, fitness=creator.FitnessMax)

toolbox = base.Toolbox()
toolbox.register("attr_str", randomwordgenerator.generate_random_words)
toolbox.register("individual", tools.initRepeat, creator.Individual,
                 toolbox.attr_str, n=1)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

ind = toolbox.individual()
print(ind)

where I get confused is when I print(ind) I get this output

<generator object initRepeat.<locals>.<genexpr> at 0x10407d888>

When I change the code to the example code however(seen below)

import random

from deap import base
from deap import creator
from deap import tools

IND_SIZE = 5

creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0))
creator.create("Individual", list, fitness=creator.FitnessMin)

toolbox = base.Toolbox()
toolbox.register("attr_float", random.random)
toolbox.register("individual", tools.initRepeat, creator.Individual,
                 toolbox.attr_float, n=IND_SIZE)

ind1 = toolbox.individual()
print(ind1)

this is the output

[0.6047278872004169, 0.8976450330325899, 0.9795210255969901, 0.5752663675034192, 0.8511975930513275]

I'm really confused as to why my example doesn't just print a string, can anyone glean some insight into this? Unfortunately they don't have examples of using strings as individuals so I'm trying to debug it on my own but am having a tough time. Any help is appreciated

回答1:

After much debate, here is the explanation as to why it will not work. The Individual is declared using the base class str, which is fine for your intent and purposes. However, when you register the individual method in the toolbox, you then use tools.initRepeat which provides a generator as an argument to the container. For individuals based on the list class this would be fine since the generator is then evaluated and stored within the list. However, since yours is based on str, the implicit conversion performed by python simply returns the string "", but does not go through the content of the generator to populate your individual. Since it seems that the tools provided by DEAP are not suited for your problem, I would suggest you write you own script for generating a population and/or individual. The following should answer your constraints:

from randomwordgenerator.randomwordgenerator import generate_random_words

from deap import base
from deap import creator
from deap import tools

POP_SIZE = 10

creator.create("FitnessMax", base.Fitness, weights=(1,))
creator.create("Individual", str, fitness=creator.FitnessMax)

toolbox = base.Toolbox()
toolbox.register("attr_str", generate_random_words, n=1)

ind = creator.Individual(toolbox.attr_str())
pop = [creator.Individual(toolbox.attr_str()) for _ in range(POP_SIZE)]

print(ind)
print(pop)

This will generate a population as a list of random words, which you can then evaluate.