DEAP / deap

Distributed Evolutionary Algorithms in Python
http://deap.readthedocs.org/
GNU Lesser General Public License v3.0
5.82k stars 1.13k forks source link

The gp.generate function tried to add a primitive of type .... #291

Open echo66 opened 6 years ago

echo66 commented 6 years ago

Greetings!

I'm a newbie at deap and, as such, I'm still trying to get the concepts right. Right now, I'm experimenting with custom input/output types using the following code:

import operator
import numpy as np
import random

from deap import algorithms
from deap import base
from deap import creator
from deap import tools
from deap import gp

creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMax)

class Output:
    def __init__(self, value):
        self.value = value

def final(x1):
    return Output(x1)

pset = gp.PrimitiveSetTyped("MAIN", [float, float, float, float, float], Output, "IN")

pset.addPrimitive(operator.add, [float,float], float)
pset.addPrimitive(operator.sub, [float,float], float)
pset.addPrimitive(operator.mul, [float,float], float)
pset.addPrimitive(operator.pow, [float,float], float)

X = [1, 2, 3, 4, 5]

def real_function_output(x1, x2, x3, x4, x5):
    return x1 + x2 * x3 - x4 * x5

def my_metric(individual):
    func = toolbox.compile(expr=individual)

    v1 = real_function_output(*X)
    v2 = func(*X).value

    z = np.abs(v1 - v2)

    #print(v1, v2, z)

    return z, 

toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("compile", gp.compile, pset=pset)

toolbox.register("evaluate", my_metric)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("mate", gp.cxOnePoint)
toolbox.register("expr_mut", gp.genHalfAndHalf, min_=0, max_=2)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)

random.seed(10)
pop = toolbox.population(n=10)
hof = tools.HallOfFame(1)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", np.mean)
stats.register("std", np.std)
stats.register("min", np.min)
stats.register("max", np.max)

algorithms.eaSimple(pop, toolbox, 0.5, 0.2, 40, stats, halloffame=hof)

When I run this, I get the following error:

IndexError: The gp.generate function tried to add a primitive of type '<class '__main__.Output'>', but there is none available.

After this, I searched for a solution in both stackoverflow, google groups and the issues board. I ended up adding a terminal like this:

pset.addTerminal(Output(123123123), Output)

After this, I still get:

IndexError: The gp.generate function tried to add a primitive of type '<class '__main__.Output'>', but there is none available.
echo66 commented 6 years ago

Is this the right place to ask?

echo66 commented 6 years ago

I'm sorry but bump this but I'm trying to understand how to use DEAP. Can someone (a) say what I did wrong or (b) point me to another forum/site where this question can be answered?

EDIT: @fmder

fmder commented 6 years ago

The root of your tree requires a primitive that produces something of type "Output" but you have only primitives producing floats. You should have at least one primitive that produces an Output.

GregoryMorse commented 2 months ago

This is related to #219.