Created
December 12, 2020 02:16
-
-
Save DMTSource/1caab2c2f3147f00116c8f6a0b83eb10 to your computer and use it in GitHub Desktop.
Example of a Deap GA problem, working with normalized individuals only
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Based on https://raw.githubusercontent.com/DEAP/deap/master/examples/ga/onemax_mp.py | |
# Using onemax(ignore the problem sorta) to show how to work with only normalized individuals | |
# Can Uses numpy individuals but no multiproc: https://deap.readthedocs.io/en/master/examples/ga_onemax_numpy.html | |
# Derek M Tishler, Dec 2020 | |
import multiprocessing | |
import random | |
import sys | |
import numpy as np | |
from deap import algorithms | |
from deap import base | |
from deap import creator | |
from deap import tools | |
def normalize_individual(ind): | |
ind[:] = ind / np.linalg.norm(ind) | |
return ind | |
def init_individual(cls, _length): | |
new_ind = normalize_individual(np.random.random((_length,))) | |
return cls(new_ind) | |
def mutate(ind): | |
ind, = tools.mutGaussian(ind, mu=0., sigma=0.5, indpb=0.05) | |
return normalize_individual(ind), | |
def crossover(ind1, ind2): | |
ind1, ind2 = tools.cxTwoPoint(ind1, ind2) | |
ind1 = normalize_individual(ind1) | |
ind2 = normalize_individual(ind2) | |
return ind1, ind2 | |
creator.create("FitnessMax", base.Fitness, weights=(1.0,)) | |
#creator.create("Individual", np.ndarray, fitness=creator.FitnessMax) # fast, but multiproc breaks... | |
creator.create("Individual", list, fitness=creator.FitnessMax) # for multiproc to work? | |
toolbox = base.Toolbox() | |
# Structure initializers | |
toolbox.register("individual", init_individual, creator.Individual, 10) | |
toolbox.register("population", tools.initRepeat, list, toolbox.individual) | |
def eval(individual): | |
# test our unit vec for fun | |
assert np.isclose(np.linalg.norm(individual) , 1.), "Individual is not Normalized" | |
return sum(individual), | |
toolbox.register("evaluate", eval) | |
toolbox.register("mate", crossover) | |
toolbox.register("mutate", mutate) | |
toolbox.register("select", tools.selTournament, tournsize=3) | |
if __name__ == "__main__": | |
#random.seed(64) | |
# Process Pool of 4 workers | |
pool = multiprocessing.Pool(processes=4) | |
toolbox.register("map", pool.map) | |
pop = toolbox.population(n=300) | |
hof = tools.HallOfFame(1, similar=np.array_equal) | |
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) | |
pop, log = algorithms.eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=10, | |
stats=stats, halloffame=hof) | |
# Show best ind and proof of it being unit vec | |
print(hof[0]) | |
print(np.linalg.norm(hof[0])) | |
pool.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output
>>> python normalized_individual_example.py
gen nevals avg std min max
0 300 2.75326 0.160146 2.31149 3.10118
1 188 2.86845 0.197205 0.90286 3.10283
2 194 2.96823 0.113104 2.03876 3.1205
3 185 3.00569 0.176245 1.07579 3.13473
4 173 3.0514 0.149009 1.22312 3.14252
5 175 3.08113 0.120845 2.05932 3.15648
6 188 3.09456 0.134366 1.99229 3.15698
7 185 3.11773 0.104459 1.94695 3.15694
8 185 3.122 0.175234 0.73787 3.16011
9 176 3.13343 0.106057 1.82101 3.15927
10 176 3.13882 0.0793346 2.4309 3.16051
[0.3048119442510624, 0.3160359444387492, 0.3384738345686081, 0.31831250487226004, 0.31558684956255006, 0.31403616967850756, 0.3268783946359163, 0.3202223778327717, 0.3012003728263482, 0.3049529091522849]
1.0