-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathae_tp1_e2.py
More file actions
143 lines (115 loc) · 5.88 KB
/
Copy pathae_tp1_e2.py
File metadata and controls
143 lines (115 loc) · 5.88 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
####################################################################
# CEIA - 16Co2024 - Algoritmos Evolutivos - TP1 - Ejercicio 2
# Gustavo J. Rivas (a1620) | Myrna L. Degano (a1618)
####################################################################
# Algoritmo Genético que encuentra el máximo de la función x^2
# Selección por ruleta
###################################################################
import random
from tabulate import tabulate
##################################################################
# Parámetros
##################################################################
print("\nINGRESE LOS PARÁMETROS PARA LA EJECUCIÓN DEL ALGORITMO (O <ENTER> PARA TOMAR LOS VALORES POR DEFAULT)\n")
TAMANIO_POBLACION = input("TAMAÑO DE LA POBLACIÓN (DEFAULT: 4): ").strip()
TAMANIO_POBLACION = int(TAMANIO_POBLACION) if TAMANIO_POBLACION else 4
LONGITUD_CROMOSOMA = input("LONGITUD DEL CROMOSOMA (DEFAULT: 5): ").strip()
LONGITUD_CROMOSOMA = int(LONGITUD_CROMOSOMA) if LONGITUD_CROMOSOMA else 5
TASA_CRUCE = input("PROBABILIDAD DE CRUCE (DEFAULT: 0.92): ").strip()
TASA_CRUCE = float(TASA_CRUCE) if TASA_CRUCE else 0.92
TASA_MUTACION = input("PROBABILIDAD DE MUTACIÓN (DEFAULT: 0.01): ").strip()
TASA_MUTACION = float(TASA_MUTACION) if TASA_MUTACION else 0.01
GENERACIONES = input("CANTIDAD DE GENERACIONES (DEFAULT: 10): ").strip()
GENERACIONES = int(GENERACIONES) if GENERACIONES else 10
###################################################################
# Aptitud (y = x^2)
###################################################################
def aptitud(cromosoma):
x = int(cromosoma, 2)
return x ** 2
###################################################################
# Inicializar la población
###################################################################
def inicializar_poblacion(tamanio_poblacion, longitud_cromosoma):
poblacion = []
for _ in range(tamanio_poblacion):
cromosoma = ""
for _ in range(longitud_cromosoma):
cromosoma = cromosoma+str(random.randint(0, 1))
poblacion.append(cromosoma)
return poblacion
###################################################################
# Selección por ruleta
###################################################################
def seleccion_ruleta(poblacion, aptitud_total):
seleccion = random.uniform(0, aptitud_total)
aptitud_actual = 0
for individuo in poblacion:
aptitud_actual = aptitud_actual+aptitud(individuo)
if aptitud_actual > seleccion:
return individuo
###################################################################
# Cruce monopunto
###################################################################
def cruce_mono_punto(progenitor1, progenitor2, tasa_cruce):
if random.random() < tasa_cruce:
punto_cruce = random.randint(1, len(progenitor1) - 1)
descendiente1 = progenitor1[:punto_cruce] + progenitor2[punto_cruce:]
descendiente2 = progenitor2[:punto_cruce] + progenitor1[punto_cruce:]
else:
descendiente1, descendiente2 = progenitor1, progenitor2
return descendiente1, descendiente2
###################################################################
# Mutación
###################################################################
def mutacion(cromosoma, tasa_mutacion):
cromosoma_mutado = ""
for bit in cromosoma:
if random.random() < tasa_mutacion:
cromosoma_mutado = cromosoma_mutado+str(int(not int(bit)))
else:
cromosoma_mutado = cromosoma_mutado+bit
return cromosoma_mutado
###################################################################
# Aplicación de operadores genéticos
###################################################################
def algoritmo_genetico(tamaño_poblacion, longitud_cromosoma, tasa_mutacion, tasa_cruce, generaciones):
poblacion = inicializar_poblacion(tamaño_poblacion, longitud_cromosoma)
for generacion in range(generaciones):
# Calcular aptitud total
aptitud_total = 0
for cromosoma in poblacion:
aptitud_total = aptitud_total+aptitud(cromosoma)
# Selección
# de progenitores con el método ruleta
progenitores = []
for _ in range(tamaño_poblacion):
progenitores.append(seleccion_ruleta(poblacion, aptitud_total))
# Cruce
descendientes = []
for i in range(0, tamaño_poblacion, 2):
descendiente1, descendiente2 = cruce_mono_punto(progenitores[i], progenitores[i + 1], tasa_cruce)
descendientes.extend([descendiente1, descendiente2])
# Mutación
descendientes_mutados = []
for descendiente in descendientes:
descendientes_mutados.append(mutacion(descendiente, tasa_mutacion))
# Elitismo - se reemplazan los peores cromosomas con los mejores progenitores
poblacion.sort(key=aptitud)
descendientes_mutados.sort(key=aptitud, reverse=True)
for i in range(len(descendientes_mutados)):
if aptitud(descendientes_mutados[i]) > aptitud(poblacion[i]):
poblacion[i] = descendientes_mutados[i]
# Mostrar el mejor individuo de la generación
mejor_individuo = max(poblacion, key=aptitud)
resultados.append([generacion + 1, aptitud_total, int(mejor_individuo, 2), aptitud(mejor_individuo)])
return max(poblacion, key=aptitud)
###################################################################
# Algoritmo genético ejecución principal
###################################################################
print("\n")
resultados = []
mejor_solucion = algoritmo_genetico(TAMANIO_POBLACION, LONGITUD_CROMOSOMA, TASA_MUTACION, TASA_CRUCE, GENERACIONES)
headers = ["Generación #", "Aptitud Total", "Mejor Individuo", "Aptitud del Mejor Individuo"]
print(tabulate(resultados, headers=headers, tablefmt="grid"))
print("\n* Mejor solución:", int(mejor_solucion, 2), "\n* Aptitud:", aptitud(mejor_solucion))