1
# This file is part of EAP.
1
# This file is part of DEAP.
3
# EAP is free software: you can redistribute it and/or modify
3
# DEAP is free software: you can redistribute it and/or modify
4
4
# it under the terms of the GNU Lesser General Public License as
5
5
# published by the Free Software Foundation, either version 3 of
6
6
# the License, or (at your option) any later version.
8
# EAP is distributed in the hope that it will be useful,
8
# DEAP is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU Lesser General Public License for more details.
13
13
# You should have received a copy of the GNU Lesser General Public
14
# License along with EAP. If not, see <http://www.gnu.org/licenses/>.
14
# License along with DEAP. If not, see <http://www.gnu.org/licenses/>.
21
20
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
23
from eap import algorithms
25
from eap import creator
26
from eap import halloffame
27
from eap import toolbox
22
from deap import algorithms
24
from deap import creator
25
from deap import tools
29
27
import sortingnetwork as sn
57
55
creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0, -1.0))
58
56
creator.create("Individual", list, fitness=creator.FitnessMin)
60
tools = toolbox.Toolbox()
58
toolbox = base.Toolbox()
63
tools.register("network", genNetwork, dimension=INPUTS, min_size=9, max_size=12)
61
toolbox.register("network", genNetwork, dimension=INPUTS, min_size=9, max_size=12)
65
63
# Structure initializers
66
tools.register("individual", creator.Individual, content_init=tools.network)
67
tools.register("population", list, content_init=tools.individual, size_init=300)
69
tools.register("evaluate", evalEvoSN, dimension=INPUTS)
70
tools.register("mate", toolbox.cxTwoPoints)
71
tools.register("mutate", mutWire, dimension=INPUTS, indpb=0.05)
72
tools.register("addwire", mutAddWire, dimension=INPUTS)
73
tools.register("delwire", mutDelWire)
75
tools.register("select", toolbox.nsga2)
64
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.network)
65
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
67
toolbox.register("evaluate", evalEvoSN, dimension=INPUTS)
68
toolbox.register("mate", tools.cxTwoPoints)
69
toolbox.register("mutate", mutWire, dimension=INPUTS, indpb=0.05)
70
toolbox.register("addwire", mutAddWire, dimension=INPUTS)
71
toolbox.register("delwire", mutDelWire)
72
toolbox.register("select", tools.selNSGA2)
80
population = tools.population()
81
hof = halloffame.ParetoFront()
77
population = toolbox.population(n=300)
78
hof = tools.ParetoFront()
80
stats = tools.Statistics(lambda ind: ind.fitness.values)
81
stats.register("Avg", tools.mean)
82
stats.register("Std", tools.std)
83
stats.register("Min", min)
84
stats.register("Max", max)
83
86
CXPB, MUTPB, ADDPB, DELPB, NGEN = 0.5, 0.2, 0.01, 0.01, 40
85
# Evaluate the individuals with an invalid fitness
86
invalid_ind = [ind for ind in population if not ind.fitness.valid]
87
fitnesses = tools.map(tools.evaluate, invalid_ind)
88
for ind, fit in zip(invalid_ind, fitnesses):
88
# Evaluate every individuals
89
fitnesses = toolbox.map(toolbox.evaluate, population)
90
for ind, fit in zip(population, fitnesses):
89
91
ind.fitness.values = fit
91
93
hof.update(population)
94
stats.update(population)
93
96
# Begin the evolution
94
97
for g in xrange(NGEN):
95
98
print "-- Generation %i --" % g
96
offsprings = [tools.clone(ind) for ind in population]
99
offsprings = [toolbox.clone(ind) for ind in population]
98
101
# Apply crossover and mutation
99
102
for ind1, ind2 in zip(offsprings[::2], offsprings[1::2]):
100
103
if random.random() < CXPB:
101
tools.mate(ind1, ind2)
104
toolbox.mate(ind1, ind2)
102
105
del ind1.fitness.values
103
106
del ind2.fitness.values
106
109
# original algorithm, we use 3 different mutations subsequently.
107
110
for ind in offsprings:
108
111
if random.random() < MUTPB:
110
113
del ind.fitness.values
111
114
if random.random() < ADDPB:
113
116
del ind.fitness.values
114
117
if random.random() < DELPB:
116
119
del ind.fitness.values
118
121
# Evaluate the individuals with an invalid fitness
119
122
invalid_ind = [ind for ind in offsprings if not ind.fitness.valid]
120
fitnesses = tools.map(tools.evaluate, invalid_ind)
123
fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
121
124
for ind, fit in zip(invalid_ind, fitnesses):
122
125
ind.fitness.values = fit
124
127
print " Evaluated %i individuals" % len(invalid_ind)
126
population = tools.select(population+offsprings, n=len(offsprings))
129
population = toolbox.select(population+offsprings, len(offsprings))
127
130
hof.update(population)
128
fits = [ind.fitness.values for ind in population]
130
# Gather all the fitnesses in one list and print the stats
131
fits_t = zip(*fits) # Transpose fitnesses for analysis
133
minimums = map(min, fits_t)
134
maximums = map(max, fits_t)
135
lenght = len(population)
136
sums = map(sum, fits_t)
137
sums2 = [sum(x*x for x in fit) for fit in fits_t]
138
means = [sum_ / lenght for sum_ in sums]
139
std_devs = [abs(sum2 / lenght - mean**2)**0.5 for sum2, mean in zip(sums2, means)]
141
print " Min %s" % ", ".join(map(str, minimums))
142
print " Max %s" % ", ".join(map(str, maximums))
143
print " Avg %s" % ", ".join(map(str, means))
144
print " Std %s" % ", ".join(map(str, std_devs))
131
stats.update(population)
146
134
best_network = sn.SortingNetwork(INPUTS, hof[0])
147
135
print best_network
148
136
print best_network.draw()
149
137
print "%i errors, length %i, depth %i" % hof[0].fitness.values
139
return population, stats, hof
151
141
if __name__ == "__main__":