Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

varAnd question #761

Open
karma-riuk opened this issue Dec 22, 2024 · 2 comments
Open

varAnd question #761

karma-riuk opened this issue Dec 22, 2024 · 2 comments

Comments

@karma-riuk
Copy link

Hello,

I'm currently trying to do some mutations over a list of str. The way I set up deap is with the following code:

creator.create("Fitness", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.Fitness)
toolbox = base.Toolbox()
toolbox.register("attr_str", fuzzer.random_individual)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_str, n=len(types)) # len(types) can be any int from 1 to 3
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("evaluate", fitness.get_fitness_of_f(globals()[func]))
toolbox.register("mate", deap_crossover)
toolbox.register("mutate", deap_mutate)
toolbox.register("select", tools.selTournament, tournsize=TOURNSIZE)

for i in range(REPS):
    population = toolbox.population(n=NPOP)
    algorithms.eaSimple(population, toolbox, CXPROB, MUPROB, NGEN, verbose=False)

As you can notice, my Individual is a list, that can contain any number (from 1 to 3) of strings.
Additionally, let me give you the deap_mutate function, as it will be useful for later:

def deap_mutate(ind):
    return creator.Individual(fuzzer.mutate(ind))

fuzzer.mutate takes in a list of strings and returns a copy of that list, with a one element mutated.

For some reason, my code kept crashing after a mutation was triggered. I was really confused why so I started digging in the code of the library, and found this: inside the varAnd function, with this piece of code that handles the mutations:

    for i in range(len(offspring)):
        if random.random() < mutpb:
            offspring[i], = toolbox.mutate(offspring[i])
            del offspring[i].fitness.values

My question is related to that little , in the third line, namely the offspring[i],. Why is it there? I am very confused by it's existence and am probably missing something.

The issue it gave me was the following, given that my individuals are a lists, when the list has one element, that element would get unpacked (because of that ,) and cause an error saying

    del offspring[i].fitness.values
        ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'fitness'

If however my list contains more than one element, then the error would come from the line where the mutation happen, saying

    offspring[i], = toolbox.mutate(offspring[i])
    ^^^^^^^^^^^^^
ValueError: too many values to unpack (expected 1)

Now, there are two fixes I found for this issue. One on my side and one on the side of the library. The one on my side is simply to wrap the individual returned in a list, in order for the mutated individual to be unpacked correctly inside the library:

def deap_mutate(ind):
    return [creator.Individual(fuzzer.mutate(ind))]

The one on the side of the library is to remove that , in the varAnd function:

    for i in range(len(offspring)):
        if random.random() < mutpb:
            offspring[i] = toolbox.mutate(offspring[i])
            del offspring[i].fitness.values

Hence my question, why are you unpacking the result of the mutation?

@fengyangsun
Copy link

I'm not sure. But I guess the mutate function is to align with the mate function or crossover function, which returns a tuple of two variables, i.e two child individuals. Mutate only has one mutated individual, so the second returned variable is left empty, But still takes a position. I think the simplest way to solve the issue is, you make the deap_mutate function also return a tuple of two variables, and leave the second empty.

@fmder
Copy link
Member

fmder commented Dec 23, 2024

@fengyangsun You are right. Plus theoretically, mutation could return an infinite number of individuals like in evolution strategies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants