-
Notifications
You must be signed in to change notification settings - Fork 0
/
linear_decider_evolver_app.py
118 lines (83 loc) · 2.87 KB
/
linear_decider_evolver_app.py
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
# coding: utf-8
#
# Copyright (c) 2021 Zoltán Máté
# All Rights Reserved.
#
# Author: Zoltán Máté <[email protected]>
#
"""
Application for evolving fixed size linear deciders
"""
import matplotlib.pyplot as plt
import random
import data
from decider import fitness
from evolver import Evolver
from linear_decider import LinearDecider
decider_size = 3
mutation_rate = 20
iteration = 40
population_size = 20
random.seed(0)
class Entity(LinearDecider):
__slots__ = 'fitness',
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fitness = fitness(self, data.values)
def breed(self):
return Entity([
coefficient + random.randint(-mutation_rate, mutation_rate)
for coefficient in self.coefficients
])
def print_population(population):
print("population = [\n {}\n]".format(",\n ".join([repr(entity) for entity in population])))
def fitnesses(population):
return [entity.fitness for entity in population]
def plot_fitness_distributions(fitness_evolution):
for iteration_count, yvalues in fitness_evolution:
plt.step(range(len(yvalues)), yvalues, label=iteration_count, where='post')
plt.xlabel('rank of decider')
plt.ylabel('fitness')
plt.title('Distribution of fitness after given iteratation')
plt.legend()
def plot_coefficients_by_fitness(population):
for idx, (label, entity) in enumerate(zip(['most fit', 'medium', 'least'], population[::len(population) // 2 - 1])):
plt.bar([(idx - 1) / 4 + x for x in range(len(entity.coefficients))], entity.coefficients, 1 / 4, label=label)
plt.xlabel('coefficient index')
plt.ylabel('coefficient value')
plt.title('Coefficients by fitness')
plt.xticks(range(decider_size))
plt.grid(axis='x')
plt.legend()
def create_initial_population():
return [
Entity(coefficients=[
random.randint(-decider_size, decider_size)
for idx in range(decider_size)
])
for idx in range(population_size)
]
def main():
population = create_initial_population()
population = Evolver.sort_by_fitness(population)
print('Initial population:')
print_population(population)
fitness_evolution = [(0, fitnesses(population))]
try:
for n in range(iteration):
population = Evolver.evolve(population)
print(n, fitnesses(population), end=" \r")
if (n + 1) % (iteration // 4) == 0:
fitness_evolution += [(n + 1, fitnesses(population))]
except KeyboardInterrupt:
pass
finally:
print('Final population:')
print_population(population)
plt.subplot(1, 2, 1)
plot_fitness_distributions(fitness_evolution)
plt.subplot(1, 2, 2)
plot_coefficients_by_fitness(population)
plt.show()
if __name__ == '__main__':
main()