What I'm finding, however, is that the output of my PSO framework is clustered around the upper left portion of the Pareto front. See here. What's more, I should have 30 individuals in my population, but somehow many of them end up having identical fitness values (there are many values sitting on top of one another at (0.0, 1.0) ). This clearly has something to do with my penalty function, but I don't see any reason why my penalty function should in general force all the individuals that are out of bounds to have output responses of (0.0, 1.0).
My code is pasted below. Does anyone have any suggestions to steer me in the right direction or shed light on why the Pareto front looks so lopsided to one side?
Thanks.
from deap import creator, base, tools, algorithms, benchmarks
import numpy as np
import array, random, operator
def F1(x):
return x[0]
def F2(x):
return G(x)*( 1 - np.sqrt(F1(x)/G(x)))
def G(x):
n = len(x)
return 1 + 9/(n-1)*np.sum(x[1:])
def eval(individual):
return F1(individual),F2(individual), G(individual),
creator.create("FitnessMin", base.Fitness, weights=(-1.0,-1.0,-1.0))
creator.create("Particle", list, fitness=creator.FitnessMin, speed=list,
smin=None, smax=None, best=None)
def generate(size, pmin, pmax, smin, smax):
part = creator.Particle(random.uniform(pmin, pmax) for _ in range(size))
part.speed = [random.uniform(smin, smax) for _ in range(size)]
part.smin = smin
part.smax = smax
return part
def updateParticle(part, best, phi1, phi2):
u1 = (random.uniform(0, phi1) for _ in range(len(part)))
u2 = (random.uniform(0, phi2) for _ in range(len(part)))
v_u1 = map(operator.mul, u1, map(operator.sub, part.best, part))
v_u2 = map(operator.mul, u2, map(operator.sub, best, part))
part.speed = list(map(operator.add, part.speed, map(operator.add, v_u1, v_u2)))
for i, speed in enumerate(part.speed):
if speed < part.smin:
part.speed[i] = part.smin
elif speed > part.smax:
part.speed[i] = part.smax
part[:] = list(map(operator.add, part, part.speed))
def feasibility(individual):
"""Feasability function for the individual. Returns True if feasible False
otherwise."""
if any(0 < individual < 1):
return True
return False
def feasible(individual):
ind = np.array(individual)
if any(ind < 0):
ind[ind<0] = 0
if any(ind > 1):
ind[ind>1] = 1
ind = list(ind)
individual = creator.Particle(ind)
return individual
toolbox = base.Toolbox()
toolbox.register("particle", generate, size=30, pmin=0.45, pmax=0.55, smin=-0.01, smax=0.01)
toolbox.register("population", tools.initRepeat, list, toolbox.particle)
toolbox.register("update", updateParticle, phi1=1, phi2=1)
toolbox.register("evaluate", evalOneMax)
toolbox.decorate("evaluate", tools.ClosestValidPenality(feasibility, feasible, 10))
pop = toolbox.population(n=25)
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)
logbook = tools.Logbook()
logbook.header = ["gen", "evals"] + stats.fields
GEN = 100
best = None
for g in range(GEN):
for part in pop:
part.fitness.values = toolbox.evaluate(part)
if not part.best or part.best.fitness < part.fitness:
part.best = creator.Particle(part)
part.best.fitness.values = part.fitness.values
if not best or best.fitness < part.fitness:
best = creator.Particle(part)
best.fitness.values = part.fitness.values
for part in pop:
toolbox.update(part, best)
# Gather all the fitnesses in one list and print the stats
logbook.record(gen=g, evals=len(pop), **stats.compile(pop))
print(logbook.stream)
front = np.array([ind.fitness.values for ind in pop])
plt.figure()
plt.scatter(front[:,0], front[:,1], c="b")
plt.axis("tight")
--
You received this message because you are subscribed to the Google Groups "deap-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to deap-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to deap-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Félix-Antoine Fortin
To unsubscribe from this group and stop receiving emails from it, send an email to deap-users+...@googlegroups.com.