Skip to content

cxSimulatedBinaryBounded raises Exception with various eta #740

@eirirlar

Description

@eirirlar

The following code fails with the Exception:
TypeError: '<=' not supported between instances of 'float' and 'complex'

The Exception occurs in the mate function cxSimulatedBinaryBounded where on some occasions beta becomes negative causing alpha to become complex and fail division.

I would have expected either proper documentation of the acceptable eta range (maybe in relation to low and up), or a repair of this bug.

import random
from deap import base, creator, tools, algorithms

# Define the problem as a maximization problem
creator.create("FitnessMax", base.Fitness, weights=(1., 1.))
creator.create("Individual", list, fitness=creator.FitnessMax)


# Define the problem-specific functions
def eval_individual(individual):
    a, b, c, d, e, f = individual
    return (a + b) ** 2, (c + d) ** 2


# Define genetic operators
toolbox = base.Toolbox()
toolbox.register("attr_float", random.uniform, 0., 1.)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=6)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

toolbox.register("evaluate", eval_individual)
toolbox.register("mate", tools.cxSimulatedBinaryBounded, eta=0.9, low=0., up=1.)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)


def main():
    population_size = 50
    generations = 20

    population = toolbox.population(n=population_size)
    CXPB, MUTPB = 0.7, 0.2

    print("Start of Evolution")

    # Evaluate the entire population
    fitnesses = list(map(toolbox.evaluate, population))
    for ind, fit in zip(population, fitnesses):
        ind.fitness.values = fit

    print("  Evaluated %i individuals" % len(population))

    for gen in range(generations):
        print("-- Generation %i --" % gen)

        # Select the next generation individuals
        offspring = toolbox.select(population, len(population))

        # Clone the selected individuals
        offspring = list(map(toolbox.clone, offspring))

        # Apply crossover and mutation on the offspring
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < CXPB:
                toolbox.mate(child1, child2)
                del child1.fitness.values
                del child2.fitness.values

        for mutant in offspring:
            if random.random() < MUTPB:
                # TODO mutate takes data out of range 0-1
                toolbox.mutate(mutant, sigma=0.1)
                del mutant.fitness.values

        # Evaluate offspring individuals
        fitnesses = list(map(toolbox.evaluate, offspring))
        for ind, fit in zip(offspring, fitnesses):
            ind.fitness.values = fit

        # Replace the old population by the offspring
        population[:] = offspring

        # Gather all the fitnesses in one list and print the stats
        fits = [ind.fitness.values[0] for ind in population]

        length = len(population)
        mean = sum(fits) / length
        sum2 = sum(x * x for x in fits)
        std = abs(sum2 / length - mean ** 2) ** 0.5

        print("  Min %s" % min(fits))
        print("  Max %s" % max(fits))
        print("  Avg %s" % mean)
        print("  Std %s" % std)

    print("-- End of (successful) evolution --")

    best_ind = tools.selBest(population, 1)[0]
    print("Best individual is %s, %s" % (best_ind, best_ind.fitness.values))


if __name__ == "__main__":
    main()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions