-
Notifications
You must be signed in to change notification settings - Fork 3
/
Population.py
117 lines (105 loc) · 4.66 KB
/
Population.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
from Species import *
from Genetics import *
class Population:
def __init__(self, n_inputs, n_outputs):
self.size = INIT_SIZE
self.n_inputs = n_inputs
self.n_outputs = n_outputs
self.chromosomes = []
self.species_list = []
self.generation = 0
self.bestperformance = 0
self.n_deltagen = 0
self.distance_threshold = DISTANCE_THRESHOLD_DEFAULT
self.delta_coding_flag = False
def create(self, mode=POPULATION_INIT_MODE):
for i in range(self.size):
chromosome = Chromosome(self.n_inputs, self.n_outputs)
if mode == "Full":
chromosome.make_full()
elif mode == "Sparse":
chromosome.make_sparse()
elif mode == "Empty":
chromosome.make_empty()
self.chromosomes.append(chromosome)
self.generation = 1
def evaluate(self, function):
for chromosome in self.chromosomes:
chromosome.set_fitness(function(chromosome.phenotype()))
def select(self, mode=SELECTION_MODE):
self.chromosomes = []
for species in self.species_list:
if mode == "Truncated":
species.truncatedSelect()
elif mode == "RouletteWheel":
species.rouletteWheelSelect()
for chromosome in species.chromosomes:
self.chromosomes.append(chromosome)
def speciate(self):
for chromosome in self.chromosomes:
if len(self.species_list) == 0:
species = Species(len(self.species_list))
species.add(chromosome)
self.species_list.append(species)
else:
flag = 0
for species in self.species_list:
representative = species.getRepresentative()
if chromosome.distance(representative) < self.distance_threshold:
species.add(chromosome)
flag = 1
break
if flag == 0:
species = Species(len(self.species_list))
species.add(chromosome)
self.species_list.append(species)
self.distance_threshold = self.getDistanceThreshold()
def reproduce(self):
avg_species_fitness_list = [species.getAvgSpeciesFitness() for species in self.species_list]
total_avg_species_fitness = np.sum(avg_species_fitness_list)
delta_parameter = 0
self.chromosomes = []
for species, avg_species_fitness in zip(self.species_list, avg_species_fitness_list):
if self.delta_coding_flag:
n_offsprings = self.size/2
else:
n_offsprings = int(self.size * avg_species_fitness / total_avg_species_fitness)
species.reproduce(n_offsprings)
self.chromosomes = self.chromosomes + species.getOffsprings()
self.delta_coding_flag = False
if DELTA_PARAMETER == "Best":
delta_parameter = self.getBestChromosome().fitness
elif DELTA_PARAMETER == "Avg":
delta_parameter = self.getAverageFitness()
if delta_parameter > self.bestperformance and not np.isclose(delta_parameter, self.bestperformance):
self.bestperformance = delta_parameter
self.n_deltagen = 0
else:
self.n_deltagen += 1
if self.n_deltagen == DELTA_GENERATIONS:
self.species_list.sort(reverse=True)
print("DELTA CODING")
if len(self.species_list) > 1:
self.chromosomes = []
self.delta_coding_flag = True
for species in self.species_list[:2]:
print(species.getBestChromosome().fitness)
self.chromosomes += species.getOffsprings()
self.n_deltagen = 0
self.species_list = []
self.chromosomes.sort(reverse=True)
self.chromosomes=self.chromosomes[:MAX_SIZE]
def incrementGeneration(self):
self.generation += 1
def getDistanceThreshold(self):
if len(self.species_list) < DISTANCE_THRESHOLD_MIN_LIMIT:
return (1 - DISTANCE_THRESHOLD_CHANGE) * self.distance_threshold
elif len(self.species_list) >= DISTANCE_THRESHOLD_MIN_LIMIT and len(
self.chromosomes) <= DISTANCE_THRESHOLD_MAX_LIMIT:
return self.distance_threshold
else:
return self.distance_threshold * (1 + DISTANCE_THRESHOLD_CHANGE)
def getAverageFitness(self):
return np.mean([c.fitness for c in self.chromosomes])
def getBestChromosome(self):
return max([s.getBestChromosome() for s in self.species_list])