Skip to content

Instantly share code, notes, and snippets.

@DMTSource
Created October 19, 2020 01:56
Show Gist options
  • Save DMTSource/74133047908e2a13e77098dfe4b8661d to your computer and use it in GitHub Desktop.
Save DMTSource/74133047908e2a13e77098dfe4b8661d to your computer and use it in GitHub Desktop.
Example of using selTournamentDCD requireing assignCrowdingDist in Deap,based on Onemax Numpy example.
# Example of using selTournamentDCD requiring assignCrowdingDist
# Based on deap/examples/ga/onemax_numpy.py
# https://github.com/DEAP/deap/blob/master/examples/ga/onemax_numpy.py
# Discussion:
# https://groups.google.com/forum/#!topic/deap-users/uU382eztuts
import random
import numpy
from deap import algorithms
from deap import base
from deap import creator
from deap import tools
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", numpy.ndarray, fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("attr_bool", random.randint, 0, 1)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n=100)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
def evalOneMax(individual):
return sum(individual),
def cxTwoPointCopy(ind1, ind2):
"""Execute a two points crossover with copy on the input individuals. The
copy is required because the slicing in numpy returns a view of the data,
which leads to a self overwritting in the swap operation. It prevents
::
>>> import numpy
>>> a = numpy.array((1,2,3,4))
>>> b = numpy.array((5,6,7,8))
>>> a[1:3], b[1:3] = b[1:3], a[1:3]
>>> print(a)
[1 6 7 4]
>>> print(b)
[5 6 7 8]
"""
size = len(ind1)
cxpoint1 = random.randint(1, size)
cxpoint2 = random.randint(1, size - 1)
if cxpoint2 >= cxpoint1:
cxpoint2 += 1
else: # Swap the two cx points
cxpoint1, cxpoint2 = cxpoint2, cxpoint1
ind1[cxpoint1:cxpoint2], ind2[cxpoint1:cxpoint2] \
= ind2[cxpoint1:cxpoint2].copy(), ind1[cxpoint1:cxpoint2].copy()
return ind1, ind2
toolbox.register("evaluate", evalOneMax)
toolbox.register("mate", cxTwoPointCopy)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
#################################################
def selTournamentDCD(individuals, k=None):
# https://github.com/DEAP/deap/blob/master/deap/tools/emo.py#L119
tools.emo.assignCrowdingDist(individuals)
# https://github.com/DEAP/deap/blob/master/deap/tools/emo.py#L145
return tools.selTournamentDCD(individuals, k)
toolbox.register("select", selTournamentDCD)
#################################################
def main():
random.seed(64)
pop = toolbox.population(n=300)
# Numpy equality function (operators.eq) between two arrays returns the
# equality element wise, which raises an exception in the if similar()
# check of the hall of fame. Using a different equality function like
# numpy.array_equal or numpy.allclose solve this issue.
hof = tools.HallOfFame(1, similar=numpy.array_equal)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("avg", numpy.mean)
stats.register("std", numpy.std)
stats.register("min", numpy.min)
stats.register("max", numpy.max)
algorithms.eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=40, stats=stats,
halloffame=hof)
return pop, stats, hof
if __name__ == "__main__":
main()
@DMTSource
Copy link
Author

Output from console:
>>>python onemax_numpy_selTournamentDCD.py
gen nevals avg std min max
0 300 50.4933 5.33822 34 64
1 195 53.5567 4.4617 43 67
2 178 55.8167 4.117 43 70
3 172 58.0633 3.93438 49 71
4 168 60.13 3.59904 48 71
5 177 61.79 3.50512 50 72
6 182 63.5567 3.46219 53 75
7 171 65.0167 3.55852 52 76
8 185 66.9633 3.08901 59 77
9 182 68.43 3.431 58 77
10 156 70.0967 3.10064 62 80
11 189 71.3267 3.02764 61 80
12 177 72.6167 3.03146 62 79
13 166 73.8933 2.7499 65 80
14 162 74.92 2.67587 66 81
15 186 75.89 2.62258 68 83
16 184 76.7967 2.762 66 84
17 175 77.8333 2.78308 68 84
18 184 78.63 2.82603 69 86
19 188 79.5567 2.69941 68 86
20 179 80.0633 3.01208 70 87
21 182 81.2167 2.80174 73 87
22 181 82.1533 2.81718 71 88
23 162 83.1233 2.70459 73 89
24 171 83.9267 2.72665 73 91
25 200 84.7067 2.74481 77 90
26 192 85.4933 2.7994 73 91
27 178 86.3133 2.83111 76 94
28 178 87.2167 2.76943 76 94
29 173 88.0767 2.56855 77 95
30 169 88.4933 3.08058 77 95
31 191 89.34 2.68658 79 95
32 184 90.1067 2.77524 80 96
33 191 90.6 2.90631 81 97
34 183 91.3233 2.86219 82 97
35 185 92.05 2.74484 84 98
36 185 92.8033 2.67918 79 99
37 192 93.2667 2.67499 84 99
38 196 93.8233 2.71271 85 99
39 168 94.4867 2.50396 84 99
40 181 94.9467 2.75266 83 100

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment