-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevolutionary_algorithm.py
More file actions
161 lines (129 loc) · 5.89 KB
/
evolutionary_algorithm.py
File metadata and controls
161 lines (129 loc) · 5.89 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from utils.functions_utils import ACKLEY_A,ACKLEY_B, ACKLEY_C, DIMENSIONS, ACKLEY_BOUND, RASTRIGIN_BOUND, SCHWEFEL_BOUND, ROSENBROCK_BOUND
from functions.benchmark_functions import ackley, rastrigin, schwefel, rosenbrock
from abc import ABC, abstractmethod
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import time
class EA(ABC):
def __init__(self, function_name, max_iterations, population_size, selected_parents, crossover_prob, mutation_prob, number_of_crossovers, genoma_size):
self.function_name = function_name
self.max_iterations = max_iterations
self.population_size = population_size
self.selected_parents = selected_parents
self.crossover_prob = crossover_prob
self.mutation_prob = mutation_prob
self.number_of_crossovers = number_of_crossovers
self.genoma_size = genoma_size
self.best_fitness = 0
self.it_best_fitness_list = []
self.it_fitness_mean_list = []
self.total_run_times = 30
self.best_fit_count = 0
def get_boundaries(self):
if self.function_name == "ackley":
boundary = ACKLEY_BOUND
elif self.function_name == "rastrigin":
boundary = RASTRIGIN_BOUND
elif self.function_name == "schwefel":
boundary = SCHWEFEL_BOUND
elif self.function_name == "rosenbrock":
boundary = ROSENBROCK_BOUND
return boundary
def get_answer(self):
return 0
def fitness(self, individual):
fitness = 0
if self.function_name == "ackley":
fitness = ackley(ACKLEY_A, ACKLEY_B, ACKLEY_C, DIMENSIONS, individual)
elif self.function_name == "rastrigin":
fitness = rastrigin(DIMENSIONS, individual)
elif self.function_name == "schwefel":
fitness = schwefel(DIMENSIONS, individual)
elif self.function_name == "rosenbrock":
fitness = rosenbrock(DIMENSIONS, individual)
return 1 / (1 + fitness)
def survival_selection(self, population):
population.sort(key=lambda individual : self.fitness(individual), reverse=True)
return population[0:self.population_size]
def update_data(self, population):
fitness_list = [self.fitness(individual) for individual in population]
self.it_fitness_mean_list.append(sum(fitness_list) / len(fitness_list))
self.it_best_fitness_list.append(self.fitness(population[0]))
def check_stopping_criteria(self, epsilon=0.005):
if abs(self.it_best_fitness_list[-1] - self.best_fitness) < epsilon:
self.best_fit_count += 1
else:
self.best_fit_count = 0
self.best_fitness = self.it_best_fitness_list[-1]
if self.best_fit_count >= 100:
return True
return False
def plot_graph(self, y, title, x_label, y_label, type='line'):
mean = np.mean(y)
std = np.std(y)
print(title)
print('Média: ', mean)
print('Desvio padrão: ', std)
sns.set_style("darkgrid")
plt.figure(figsize=(12, 4))
if type == 'bar':
plt.bar(range(1,len(y)+1), y, color='#6141ac')
else:
plt.plot(y, color='#6141ac', linewidth=2)
plt.axhline(y=mean, color='#0097b2', linestyle='--')
plt.axhline(y=mean + std, color='#0097b2', linestyle='--')
plt.axhline(y=mean - std, color='#0097b2', linestyle='--')
plt.xlabel(x_label)
plt.ylabel(y_label)
plt.title(title)
plt.show()
def execute(self):
num_converged_executions = 0
exec_fit_mean = []
exec_best_individual = []
exec_num_iterations = []
exec_best_fit = []
time_list = []
for _ in range(self.total_run_times):
start_time = time.time()
population, num_iterations = self.find_solution()
time_list.append(time.time() - start_time)
exec_best_individual.append(population[0])
exec_num_iterations.append(num_iterations)
exec_best_fit.append(self.it_best_fitness_list[-1])
exec_fit_mean.append(self.it_fitness_mean_list[-1])
epsilon = 0.005
num_converged_executions += 1 if (1-self.it_best_fitness_list[-1] < epsilon) else 0
print('Número de execuções convergidas: ', num_converged_executions)
## Informações sobre todas as execuções
# Tempo de execução
self.plot_graph(time_list, 'Tempo de execução por execução', 'Execução', 'Tempo (s)', 'bar')
# Melhor indivíduo por execução
self.plot_graph(exec_best_fit, 'Melhor indivíduo por execução', 'Execução', 'Fitness', 'bar')
# Iterações por execução
self.plot_graph(exec_num_iterations, 'Número de iterações por execução', 'Execução', 'Número de iterações', 'bar')
# Média do fitness por execução
self.plot_graph(exec_fit_mean, 'Fitness médio por execução', 'Execução', 'Fitness médio', 'bar')
## Informações sobre a última execução
# Melhor indivíduo da última execução
print('Melhor indivíduo da última execução: ', exec_best_individual[-1])
# Melhor indivíduo por iteração
self.plot_graph(self.it_best_fitness_list, 'Melhor indivíduo por iteração', 'Iteração', 'Fitness')
# Fitness médio por iteração
self.plot_graph(self.it_fitness_mean_list, 'Fitness médio por iteração', 'Iteração', 'Fitness médio')
@abstractmethod
def generate_initial_population(self):
pass
@abstractmethod
def parent_selection(self, population):
pass
@abstractmethod
def mutation(self, population):
pass
@abstractmethod
def crossover(self, population):
pass
@abstractmethod
def find_solution(self):
pass