I am developing a simple genetic algorithm using Python and the Deap library . At the end of all I am launching the eaSimple function to have the population evolved, but I keep having the following error : "object 'int' has no len()'. The algorithm is very basic and its mostly cut and pasted from a model algorithm taken from a course, which is allegedly working fine. Here is the involved section of code :
def safediv (dividend, divisor):
if divisor != 0:
return dividend / divisor
else:
return dividend
#select the primitives
pset = gp.PrimitiveSet("main", 6) #arity is 6 because as we'll see, the primitiveset 's function is calculated over 6 param (f12,d12, f1, etc..)'
pset.addPrimitive(operator.add, 2)
pset.addPrimitive(operator.mul, 2)
pset.addPrimitive(operator.sub, 2)
pset.addPrimitive(safediv,2)
creator.create ("MyFitness", base.Fitness, weights=(-1.0,))
creator.create ("Individual", gp.PrimitiveTree, fitness = creator.MyFitness)
toolbox = base.Toolbox()
toolbox.register("expr",
gp.genGrow,
pset=pset,
min_ = 1, # minimum depth of primitivetree
max_ = 4) # maximum depth of primitivetree (max of nested primitive calls)
toolbox.register("individual", #function for creating the single individual
tools.initIterate, #initIterate takes the first arg (creator.Individual) and builds it with the structur coming from the second
creator.Individual, # (tools.expr)
toolbox.expr)
toolbox.register ("compile", gp.compile, pset = pset)
toolbox.register("population",
tools.initRepeat,
list,
toolbox.individual)
#parameters to pass to the eaSimple algorithm
toolbox.register("evaluate", MyError,y_train = y_train_set, x_train_ambo = x_train_set_ambo, x_train_extract =x_train_set_extract )
toolbox.register("mate",tools.cxUniform , indpb = 0.3) #Uniform swaps individual bits between the two parents, rather than segments
#(see book)
toolbox.register("expr_mut", gp.genFull, min_=0,max_=2)
toolbox.register("mutate",gp.mutUniform, expr=toolbox.expr_mut,pset= pset)
toolbox.register("select", tools.selTournament, tournSize = 3) #tournaments allow to distribute the selection between multiple processors
#as picking individuals by 3 at a time can have each #tournament performed
#on a different cpu and then the selection parallelized
#decorators to limit the growth of the PrimitiveTree
toolbox.decorate("mate", gp.staticLimit(key=operator.attrgetter("height"), max_value=17))
toolbox.decorate("mutate", gp.staticLimit(key=operator.attrgetter("height"), max_value=17))
pop = toolbox.population(n=300)
hof = tools.HallOfFame(1)
stat_fit = tools.Statistics (key=lambda ind: ind.fitness.values)
stat_size = tools.Statistics ( key=len)
mstats = tools.MultiStatistics(fitness = stat_fit, size = stat_size)
mstats.register ("min", np.min)
mstats.register ("max", np.max)
mstats.register ("avg", np.mean)
mstats.register ("std", np.std)
pop, log = algorithms.eaSimple(population = pop,
toolbox = toolbox,
cxpb = 0.5,
mutpb = 0.1,
ngen = num_gen,
stats= mstats,
halloffame=hof
,
verbose=True
)
The MyError function returns an int, I am confident its working fine since I debugged it accurately, thats why I didn't include the code.
Any idea ?