-
Notifications
You must be signed in to change notification settings - Fork 0
/
genetic_algorithm.py
122 lines (88 loc) · 3.27 KB
/
genetic_algorithm.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
119
120
121
122
"""
This script contains the Genetic Algorith. This algorithm contains
the selection of the parents for each generation, crossover to generate
new offsprings in the next generation and mutation of the offsprings
to create more variety of offsprings.
"""
import numpy as np
import copy
from settings import *
class Genetic_Algorithm(object):
def __init__(self):
pass
def parents_selection(self, weights, bias, fitness):
best_snakes_fitness = []
best_snakes_idx = []
parents_weights = []
parents_bias = []
probability = []
for _ in range(num_parents):
top_snake_idx = fitness.index(max(fitness))
best_snakes_fitness.append(max(fitness))
best_snakes_idx.append(top_snake_idx)
parents_weights.append(weights[top_snake_idx])
parents_bias.append(bias[top_snake_idx])
fitness.pop(top_snake_idx)
weights.pop(top_snake_idx)
bias.pop(top_snake_idx)
sum_probability = 0
fitness_percentage = np.divide(best_snakes_fitness, sum(best_snakes_fitness))
for i in range(len(best_snakes_fitness)):
sum_probability += fitness_percentage[i] # Note that minimum fitscore is always 1
probability.append(sum_probability)
return (best_snakes_fitness, best_snakes_idx, parents_weights, parents_bias, probability)
def uniform_crossover(self, parents_weights, parents_bias, probability):
offspring_weights = []
offspring_bias = []
select_parent1 = True
select_parent2 = True
count = 0
for i in range(num_offspring):
while True:
parent1 = np.random.uniform(0,1)
parent2 = np.random.uniform(0,1)
for j in range(len(probability)):
if parent1 < probability[j]:
if select_parent1:
parent_idx1 = j
select_parent1 = False
if parent2 < probability[j]:
if select_parent2:
parent_idx2 = j
select_parent2 = False
select_parent1 = True
select_parent2 = True
if parent_idx1 != parent_idx2:
weights_temp1 = []
for k in range(len(layer)-1):
weights_temp2 = np.empty((layer[k], layer[k+1]))
for l in range(weights_temp2.shape[0]):
for m in range(weights_temp2.shape[1]):
if np.random.uniform(0,1) < 0.5:
weights_temp2[l, m] = parents_weights[parent_idx1][k][l,m]
else:
weights_temp2[l, m] = parents_weights[parent_idx2][k][l,m]
weights_temp1.append(weights_temp2)
offspring_weights.append(weights_temp1)
bias_temp1 = []
for k in range(len(layer)-1):
bias_temp2 = np.empty((1, layer[k+1]))
for l in range(bias_temp2.shape[0]):
for m in range(bias_temp2.shape[1]):
if np.random.uniform(0,1) < 0.5:
bias_temp2[l, m] = parents_bias[parent_idx1][k][l,m]
else:
bias_temp2[l, m] = parents_bias[parent_idx2][k][l,m]
bias_temp1.append(bias_temp2)
offspring_bias.append(bias_temp1)
break
return (offspring_weights, offspring_bias)
def uniform_mutation(self, offspring_weights):
offspring_weights_mutated = copy.deepcopy(offspring_weights)
for i in range(num_offspring):
for j in range(len(layer)-1):
for k in range(layer[j]):
for l in range(layer[j+1]):
if np.random.uniform(0,1) < mutation_rate:
offspring_weights_mutated[i][j][k,l] = np.random.choice(np.arange(-1, 1, step=0.01))
return (offspring_weights_mutated)