1
# This file is part of DEAP.
3
# DEAP is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU Lesser General Public License as
5
# published by the Free Software Foundation, either version 3 of
6
# the License, or (at your option) any later version.
8
# DEAP is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU Lesser General Public License for more details.
13
# You should have received a copy of the GNU Lesser General Public
14
# License along with DEAP. If not, see <http://www.gnu.org/licenses/>.
18
from deap import algorithms
20
from deap import creator
21
from deap import tools
22
from deap import cTools
24
import sortingnetwork as sn
28
def evalEvoSN(individual, dimension):
29
network = sn.SortingNetwork(dimension, individual)
30
return network.assess(), network.length, network.depth
32
def genWire(dimension):
33
return (random.randrange(dimension), random.randrange(dimension))
35
def genNetwork(dimension, min_size, max_size):
36
size = random.randint(min_size, max_size)
37
return [genWire(dimension) for i in xrange(size)]
39
def mutWire(individual, dimension, indpb):
40
for index, elem in enumerate(individual):
41
if random.random() < indpb:
42
individual[index] = genWire(dimension)
44
def mutAddWire(individual, dimension):
45
index = random.randint(0, len(individual))
46
individual.insert(index, genWire(dimension))
48
def mutDelWire(individual):
49
index = random.randrange(len(individual))
52
creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0, -1.0))
53
creator.create("Individual", list, fitness=creator.FitnessMin)
55
toolbox = base.Toolbox()
58
toolbox.register("network", genNetwork, dimension=INPUTS, min_size=9, max_size=12)
60
# Structure initializers
61
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.network)
62
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
64
toolbox.register("evaluate", evalEvoSN, dimension=INPUTS)
65
toolbox.register("mate", tools.cxTwoPoint)
66
toolbox.register("mutate", mutWire, dimension=INPUTS, indpb=0.05)
67
toolbox.register("addwire", mutAddWire, dimension=INPUTS)
68
toolbox.register("delwire", mutDelWire)
69
toolbox.register("select", cTools.selNSGA2)
74
population = toolbox.population(n=300)
75
hof = tools.ParetoFront()
77
stats = tools.Statistics(lambda ind: ind.fitness.values)
78
stats.register("Avg", tools.mean)
79
stats.register("Std", tools.std)
80
stats.register("Min", min)
81
stats.register("Max", max)
83
CXPB, MUTPB, ADDPB, DELPB, NGEN = 0.5, 0.2, 0.01, 0.01, 40
85
# Evaluate every individuals
86
fitnesses = toolbox.map(toolbox.evaluate, population)
87
for ind, fit in zip(population, fitnesses):
88
ind.fitness.values = fit
90
hof.update(population)
91
stats.update(population)
94
for g in xrange(NGEN):
95
print "-- Generation %i --" % g
96
offspring = [toolbox.clone(ind) for ind in population]
98
# Apply crossover and mutation
99
for ind1, ind2 in zip(offspring[::2], offspring[1::2]):
100
if random.random() < CXPB:
101
toolbox.mate(ind1, ind2)
102
del ind1.fitness.values
103
del ind2.fitness.values
105
# Note here that we have a different sheme of mutation than in the
106
# original algorithm, we use 3 different mutations subsequently.
107
for ind in offspring:
108
if random.random() < MUTPB:
110
del ind.fitness.values
111
if random.random() < ADDPB:
113
del ind.fitness.values
114
if random.random() < DELPB:
116
del ind.fitness.values
118
# Evaluate the individuals with an invalid fitness
119
invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
120
fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
121
for ind, fit in zip(invalid_ind, fitnesses):
122
ind.fitness.values = fit
124
print " Evaluated %i individuals" % len(invalid_ind)
126
population = toolbox.select(population+offspring, len(offspring))
127
hof.update(population)
128
stats.update(population)
130
print " Min %s" % stats.Min[0][-1][0]
131
print " Max %s" % stats.Max[0][-1][0]
132
print " Avg %s" % stats.Avg[0][-1][0]
133
print " Std %s" % stats.Std[0][-1][0]
135
best_network = sn.SortingNetwork(INPUTS, hof[0])
137
print best_network.draw()
138
print "%i errors, length %i, depth %i" % hof[0].fitness.values
140
return population, stats, hof
142
if __name__ == "__main__":