Hi, I am running some tests to checkout DEAP. I have this code to instantiate a simple population of simple individuals. The individuals have features that is 1 list of integers. Fitness is calculated by summing the count of feature integers that match a goal integer. And then I run selStochasticUniversalSampling to return a new list.
import numpy as np
import deap.tools as tools
class Individual():
def __init__(self):
self.features = np.random.randint(low=0,high=10,size=5)
self.goal = 5
self.fitness = 0
def fitness_calc(self):
self.fitness = sum(self.features==self.goal)
class Population():
def __init__(self):
self.count_individual = 100
self.list_individual = []
for i in range(self.count_individual):
self.list_individual.append(Individual())
def fitness_calc(self):
for individual in self.list_individual:
individual.fitness_calc()
my_population = Population()
my_population.fitness_calc()
sel_population = tools.selStochasticUniversalSampling(individuals=my_population.list_individual,
k=10,
fit_attr="fitness")
print("complete")
This fails with traceback:
Traceback (most recent call last):
File "/home/calvin/PycharmProjects/go/go_test.py", line 28, in <module>
sel_population = tools.selStochasticUniversalSampling(individuals=my_population.list_individual,k=10,fit_attr="fitness")
File "/home/calvin/.local/lib/python3.6/site-packages/deap/tools/selection.py", line 197, in selStochasticUniversalSampling
sum_fits = sum(getattr(ind, fit_attr).values[0] for ind in individuals)
File "/home/calvin/.local/lib/python3.6/site-packages/deap/tools/selection.py", line 197, in <genexpr>
sum_fits = sum(getattr(ind, fit_attr).values[0] for ind in individuals)
AttributeError: 'numpy.int64' object has no attribute 'values'
Does the fit_attr have to be of a certain datatype? Is there a DEAP fitness datatype that must be used?
pset = gp.PrimitiveSet("MAIN", arity=n, prefix='x')
pset.addPrimitive(operators.addition, 2)
pset.addPrimitive(operators.subtract, 2)
pset.addPrimitive(operators.multiply, 2)
# and many more...
# One optimization objective.
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
# Arithmetic expression.
creator.create("Tree", gp.PrimitiveTree, pset=pset)
# Individual is a list consisting of n_components trees.
creator.create("Individual", list, fitness=creator.FitnessMin)
toolbox = base.Toolbox()
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=MIN_TREE_HEIGHT, max_=MAX_TREE_HEIGHT)
toolbox.register("tree", tools.initIterate, creator.Tree, toolbox.expr)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.tree, n=pop_size)
# Population.
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
def feasible(individual):
"""Feasability function for the individual. Returns True if feasible False
otherwise."""
if int(individual[2]) < int(individual[1]):
return True
return False
toolbox.register("evaluate", evalOneMax)
toolbox.decorate("evaluate", tools.DeltaPenality(feasible,7.0))
7.0 is necessary? @fmder . If I don't insert 7 it gives me an error
@FranciscoPalomares Documentation for DeltaPenalty and tutorial . 7.0 is the penalty applied to invalid individuals. It is a required argument.
Diversity strongly depends on your response domain. If your population converges too fast you can try to play with crossover and mutation parameters. Moreover having selection with randomness (like tournament with a low number of participant) may help.