1from deap_er import creator
2from deap_er import tools
3from deap_er import base
4import numpy
5
6
7numpy.random.seed(1234) # disables randomization
8
9
10SIZE = 5
11MU, LAMBDA = 10, 10
12MIN_BOUND = numpy.zeros(SIZE)
13MAX_BOUND = numpy.ones(SIZE)
14EPS_BOUND = 2.e-5
15NGEN = 500
16
17
18def validity(individual):
19 if any(individual < MIN_BOUND) or any(individual > MAX_BOUND):
20 return False
21 return True
22
23
24def feasible(individual):
25 feasible_ind = numpy.array(individual)
26 feasible_ind = numpy.maximum(MIN_BOUND, feasible_ind)
27 feasible_ind = numpy.minimum(MAX_BOUND, feasible_ind)
28 return feasible_ind
29
30
31def distance(feasible_ind, original_ind):
32 return sum((f - o)**2 for f, o in zip(feasible_ind, original_ind))
33
34
35def setup():
36 creator.create("FitnessMin", base.Fitness, weights=(-1.0, -1.0))
37 creator.create("Individual", list, fitness=creator.FitnessMin)
38
39 toolbox = base.Toolbox()
40 toolbox.register("evaluate", tools.bm_zdt_1)
41 toolbox.decorate("evaluate", tools.ClosestValidPenalty(validity, feasible, 1.0e+6, distance))
42
43 pop = [creator.Individual(x) for x in (numpy.random.uniform(0, 1, (MU, SIZE)))]
44 for ind in pop:
45 ind.fitness.values = toolbox.evaluate(ind)
46 strategy = tools.StrategyMultiObjective(
47 population=pop,
48 sigma=1.0,
49 offsprings=LAMBDA,
50 survivors=MU
51 )
52 toolbox.register("generate", strategy.generate, creator.Individual)
53 toolbox.register("update", strategy.update)
54
55 stats = tools.Statistics(lambda x: x.fitness.values)
56 stats.register("min", numpy.min, axis=0)
57 stats.register("max", numpy.max, axis=0)
58
59 logbook = tools.Logbook()
60 logbook.header = ["gen", "nevals"] + (stats.fields if stats else [])
61
62 return toolbox, strategy, stats, logbook
63
64
65def print_results(valid, parents):
66 hv = tools.hypervolume(parents, [11.0, 11.0])
67 if not hv > 110 and valid != len(parents):
68 raise RuntimeError('Evolution failed to converge.')
69 print(f"\nNumber of valid individuals is {valid}/{len(parents)}"
70 f" with a hypervolume of {hv:.2f}.")
71 print(f'Evolution converged correctly.')
72
73
74def main():
75 toolbox, strategy, stats, logbook = setup()
76
77 fitness_history = []
78 for gen in range(NGEN):
79 population = toolbox.generate()
80 fitness = toolbox.map(toolbox.evaluate, population)
81
82 for ind, fit in zip(population, fitness):
83 ind.fitness.values = fit
84 fitness_history.append(fit)
85
86 toolbox.update(population)
87 record = stats.compile(population) if stats is not None else {}
88 logbook.record(gen=gen, nevals=len(population), **record)
89 print(logbook.stream)
90
91 num_valid = 0
92 for ind in strategy.parents:
93 dist = distance(feasible(ind), ind)
94 if numpy.isclose(dist, 0.0, rtol=1.e-5, atol=1.e-5):
95 num_valid += 1
96
97 print_results(num_valid, strategy.parents)
98
99
100if __name__ == "__main__":
101 main()