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