-
Notifications
You must be signed in to change notification settings - Fork 2
/
species.py
63 lines (46 loc) · 1.81 KB
/
species.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
import operator
import random
class Species:
def __init__(self, player):
self.players = []
self.average_fitness = 0
self.threshold = 1.2
self.players.append(player)
self.benchmark_fitness = player.fitness
self.benchmark_brain = player.brain.clone()
self.champion = player.clone()
self.staleness = 0
def similarity(self, brain):
similarity = self.weight_difference(self.benchmark_brain, brain)
return self.threshold > similarity
@staticmethod
def weight_difference(brain_1, brain_2):
total_weight_difference = 0
for i in range(0, len(brain_1.connections)):
for j in range(0, len(brain_2.connections)):
if i == j:
total_weight_difference += abs(brain_1.connections[i].weight -
brain_2.connections[j].weight)
return total_weight_difference
def add_to_species(self, player):
self.players.append(player)
def sort_players_by_fitness(self):
self.players.sort(key=operator.attrgetter('fitness'), reverse=True)
if self.players[0].fitness > self.benchmark_fitness:
self.staleness = 0
self.benchmark_fitness = self.players[0].fitness
self.champion = self.players[0].clone()
else:
self.staleness += 1
def calculate_average_fitness(self):
total_fitness = 0
for p in self.players:
total_fitness += p.fitness
if self.players:
self.average_fitness = int(total_fitness / len(self.players))
else:
self.average_fitness = 0
def offspring(self):
baby = self.players[random.randint(1, len(self.players)) - 1].clone()
baby.brain.mutate()
return baby