Ejemplo de Un Algoritmo Genético
Ejemplo de Un Algoritmo Genético
Ejemplo de Un Algoritmo Genético
Descripción de la metodología 4
Descripción Herramientas 6
Código 8
Análisis de gráficas 15
Parte 1: funcionamiento del algoritmo con/sin elitismo. 15
Parte 2: gráficas con modificaciones de parámetros 18
Conclusión 21
Hacer un programa que utilice un Algoritmo Genético Canónico para buscar un
máximo de la función:
f(x) = (x/coef)2 en el dominio [0 , 230 -1]
donde coef = 230 -1
Opción A:
● El programa debe mostrar, finalmente, el Cromosoma correspondiente al
valor máximo, el valor máximo, mínimo y promedio obtenido de cada
población.
Página 1
considere oportunos en los parámetros de entrada de manera de enriquecer
sus conclusiones.
Opción B:
Se entiende por elite a un grupo pequeño que por algún motivo, característica,
facultad o privilegio es superior o mejor en comparación al grueso de una población
determinada; con cualidades o prerrogativas de las que la gran mayoría no
disfrutan.
Un algoritmo genético, desde el punto de vista de la optimización, es un método
poblacional de búsqueda dirigida basada en probabilidad. Bajo una condición
bastante débil, que el algoritmo mantenga elitismo, es decir, guarde siempre al
mejor elemento de la población sin hacerle ningún cambio, se puede demostrar que
el algoritmo converge en probabilidad al óptimo. En otras palabras, al aumentar el
número de iteraciones, la probabilidad de tener el óptimo en la población tiende a
uno.
Luego el método más utilizado para mejorar la convergencia de los algoritmos
genéticos es el elitismo.
Este método consiste básicamente para nuestro trabajo en realizar la etapa de
selección de la siguiente manera:
* Se realiza un muestreo en una élite de “ere” miembros es decir para nuestro
ejercicio se seleccionan dos cromosomas que poseen el mejor fitness de entre los
mejores de la población inicial y se incorporan directamente a la población siguiente,
sin pasar por la población intermedia.
*El proceso se repite para cada población que se va generando hasta completar el
número de veces que se ejecutará el algoritmo genético. Se solicita la ejecución de
100 iteraciones.
Para esta segunda parte del trabajo se deberá utilizar elitismo, mostrar nuevamente
las salidas por pantalla y las gráficas solicitadas en la PARTE A pero en este caso
considerando la aplicación de elitismo.
Página 2
Descripción de la metodología
def f(x)
Esta función devuelve el valor del fitness de un cromosoma, es decir, qué tan bien
aplica dicho cromosoma en la función dada. El parámetro funcion refiere al
cromosoma aplicado a la función f(x), y total es el parámetro que indica la sumatoria
de todos los cromosomas aplicados a la función f(x) de la población.
def ruleta()
Dentro de esta función se crea un arreglo de longitud variable (dado que al utilizar
los números redondeados la suma de todos los fitness no siempre dan como
resultado el mismo entero) asignando en cada posición un único cromosoma
repetido la cantidad de veces que indique su fitness.
Luego con un número aleatorio, de 0 a la longitud del arreglo de la ruleta,
obtenemos el cromosoma elegido.
def poblacion_inicial()
Página 3
de 30 genes para cada entidad, guardandolos en el arreglo llamado
str_cromosomas. Luego convertirá los “string” a sus enteros correspondientes en
el sistema decimal, para guardarlos en el arreglo int_cromosomas y poder
trabajarlos matemáticamente luego.
def elitismo()
Esta función hace que los dos mejores cromosomas, juzgándolos por su fitness,
pasen directamente a la próxima población sin ser modificados. Esto lo hace
buscando entre todos los cromosomas los dos de mayor fitness y guardándolos en
las dos últimas posiciones de la siguiente población.
def crossover()
def mutación()
Primero valida si se realizará una mutación para el cromosoma con el que esté
trabajando, comparando probabilidades de la misma forma que la función anterior.
Si se da, toma un valor cualquiera de 0 a 30 para ubicarse en dicha posición y
cambiar el valor del gen. Es decir, si el gen es 0 cambiarlo a 1 o viceversa.
Página 4
Descripción Herramientas
Elegimos utilizar Python porque nos pareció un lenguaje muy potente en
cuanto a funciones matemáticas y su implementación. Además de que lo usamos
como excusa para acercarnos un poco más a este lenguaje, y aprender cómo
utilizarlo.
Como IDE decidimos utilizar PyCharm, ya que uno de nosotros estaba un
tanto familiarizado con este entorno.
Si bien al comienzo fue un gran desafío programar, aprender el lenguaje y la
metodología de los algoritmos genéticos logramos completar la tarea asignada con
resultados gratificantes.
Utilizamos las siguientes 3 bibliotecas que ya vienen junto con PyCharm:
- random
- matplotlib.pyplot
- numpy
- pandas
- os
random nos permitió generar números aleatorios para poder hacer probabilidades,
dentro de la ruleta, el crossover, la mutación.
numpy nos ayudó a generar arreglos de números que utilizamos para hacer el eje x
de las gráficas.
pandas, la utilizamos para poder escribir la tabla de todas las poblaciones en excel.
os nos permite acceder a funciones del sistema operativo, en nuestro caso buscar
el archivo de Excel y abrirlo.
Página 5
Forma de trabajo abordada
Página 6
Código
import random
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
# Constantes
tam_poblacion = 10
corridas = 0
coef = (2 ** 30) - 1
str_cromosomas = [""] * tam_poblacion
int_cromosomas = [0] * tam_poblacion
array_fitness = [0] * tam_poblacion
chances_crossover = 0.75
chances_mutacion = 0.05
# Funciones
if opcion_elite.lower() == 's':
return True
else:
return False
Página 7
# Hace la función matemática
def f(x):
return (x / coef) ** 2
# Calcula fitness
def fitness(funcion, total):
return funcion / total
# Genera la ruleta
def ruleta():
base = 0
cant_casilleros = 0
Página 8
fila = tam_poblacion
matriz_cromosomas = [[0 for j in range(col)] for i in range(fila)]
for f in range(0, fila):
for c in range(0, col):
matriz_cromosomas[f][c] = str(random.randint(0, 1))
for f in range(0, fila):
str_cromosomas[f] = ""
for c in range(0, col):
str_cromosomas[f] = str_cromosomas[f] + matriz_cromosomas[f][c]
for f in range(0, fila):
int_cromosomas[f] = int(str_cromosomas[f], 2)
# Hace el crossover
def crossover():
for i in range(0, n, 2):
cros = random.random()
# Hace mutación
def mutacion():
for i in range(0, n):
muta = random.random()
Página 9
if muta < chances_mutacion:
pos_mutacion = random.randint(0, 29)
cromosoma1 = str_cromosomas[i]
if cromosoma1[pos_mutacion] == "1":
cromosoma1 = cromosoma1[:pos_mutacion] + "0" + cromosoma1[pos_mutacion +
1:]
else:
cromosoma1 = cromosoma1[:pos_mutacion] + "1" + cromosoma1[pos_mutacion +
1:]
str_cromosomas[i] = cromosoma1
int_cromosomas[i] = int(cromosoma1, 2)
# Hace elitismo
def elitismo():
busca1 = 0
valor1 = 0
busca2 = 0
valor2 = 0
for i in range(0, tam_poblacion):
if busca1 < f(int_cromosomas[i]):
busca1 = f(int_cromosomas[i])
valor1 = i
for i in range(0, tam_poblacion):
if i!= valor1 and busca2 < f(int_cromosomas[i]):
busca2 = f(int_cromosomas[i])
valor2 = i
nueva_poblacion[8] = str_cromosomas[valor1]
nueva_poblacion[9] = str_cromosomas[valor2]
str_cromosomas[8] = nueva_poblacion[8]
str_cromosomas[9] = nueva_poblacion[9]
int_cromosomas[8] = int(nueva_poblacion[8], 2)
int_cromosomas[9] = int(nueva_poblacion[9], 2)
Página 10
# Main
continuar = True
while continuar:
mvp_fitness = [0] * 3
mvp_fitness[1] = 0
elite = valida_elitismo()
poblacion_inicial()
Página 11
for j in range(0, tam_poblacion):
if mvp_fitness[1] < f(int_cromosomas[j]):
mvp_fitness[0] = i + 1
mvp_fitness[1] = f(int_cromosomas[j])
mvp_fitness[2] = str_cromosomas[j]
array_maximos[i] = f(mayor)
array_minimos[i] = f(menor)
array_promedios[i] = acum_promedio / 10
tabla[0] = f(menor)
tabla[1] = f(mayor)
tabla[2] = bin(mayor)
tabla[3] = acum_promedio/10
datos[i] = tabla
if elite:
elitismo()
n = tam_poblacion - 2
else:
n = tam_poblacion
crossover()
mutacion()
Página 12
t = pd.DataFrame(data=datos, columns=["Mínimo", "Máximo", "Cromosoma Máx.",
"Promedio"])
t1 = pd.DataFrame(data=mvp_fitness, index=["Población", "Número", "Cromosoma"],
columns=["MVP"])
outfile = "Tabla.xlsx"
writer = pd.ExcelWriter(outfile, engine="xlsxwriter")
t.to_excel(writer, sheet_name="Tabla")
t1.to_excel(writer, sheet_name="MVP")
writer.save()
continuar_aux = ''
while continuar_aux.lower() != 'n' and continuar_aux.lower() != 's':
if continuar_aux.lower() == 's':
continuar = True
else:
continuar = False
Página 13
Análisis de gráficas
Página 14
Figura 2. Gráfica de ejecución del algoritmo sin elitismo y con 100 corridas.
Figura 3. Gráfica de ejecución del algoritmo sin elitismo y con 200 corridas.
Página 15
Figura 4. Gráfica de ejecución del algoritmo con elitismo y con 100 iteraciones.
Tablas correspondientes:
Página 16
Parte 2: gráficas con modificaciones de parámetros
En esta segunda parte, el análisis se centrará en cómo cambia el
funcionamiento del algoritmo al modificar el parámetro de la mutación. Fue realizado
en las siguientes formas y variaciones:
● Gráficas SIN MUTACIONES
○ Gráfica SIN ELITISMO
Página 17
○ Gráfica CON ELITISMO
Figura 6. Gráficas de ejecución del algoritmo sin mutación y con elitismo.
A diferencia de los resultados sin elitismo, vemos como ahora los máximos se
mantienen, dado que en cada población nueva generada existirán ciertos
cromosomas con características elitistas que no se verán sometidos al crossover,
sino que por el contrario se incorporarán a la población siguiente directamente. Esto
implica que los valores máximos sólo pueden mantenerse o crecer. Sin embargo, la
falta de mutaciones en el algoritmo hace que existan altas probabilidades de que
dichos valores se estanquen rápidamente, dada la invariancia de estos
cromosomas.
● Gráficas CON MUTACIÓN
○ Gráfica SIN ELITISMO
Figura 7. Gráficas de ejecución del algoritmo con mutación y sin elitismo.
Página 18
En la figura 7 podemos apreciar que la aplicación del método de mutación
mejora notablemente el funcionamiento del algoritmo, brindando un mayor alcance
de posibilidades en la búsqueda de individuos y evitando, en líneas generales, el
estancamiento, logrando una convergencia más atenuada a lo largo de las corridas.
Sin embargo, el hecho de no aplicar elitismo implica correr con el riesgo de perder,
durante la selección, ciertos individuos que eran altamente aptos.
Figura 8. Gráficas de ejecución del algoritmo con mutación y con elitismo.
Página 19
Conclusión
Podríamos decir que la construcción de un algoritmo genético es necesaria
para comprender el funcionamiento de esta metodología de optimización de tareas.
Sin embargo, consideramos que no es suficiente. El posterior análisis de datos de
su comportamiento es fundamental, puesto que nos permitirá detectar cuestiones
teóricas que son determinantes en el algoritmo.
En primer lugar, la importancia de la existencia de mutaciones en el
algoritmo, sobre todo a medida que el número de poblaciones generadas aumenta.
El algoritmo genético debe, no sólo seleccionar de entre lo mejor que ha
encontrado, sino procurar encontrar mejores individuos. En esto, la mutación es un
elemento clave, dado que permite optimizar la exploración y el sondeo de la mayor
cantidad de individuos posibles.
Por otro lado, el algoritmo no debe perder de vista a los mejores individuos
encontrados: si bien las posibilidades de selección de éstos es alta, no siempre es
total, por lo que también resulta conveniente asegurar la continuidad de estos
individuos en el tiempo.
En el análisis de las gráficas consideramos también la aplicación (o no) del
método elitista en el algoritmo. Esto nos permitió advertir los beneficios que este
fenómeno trae al momento de buscar una convergencia óptima: población tras
población, los individuos más aptos van perdurando en el tiempo siempre y cuando
no se encuentre ningún individuo mejor. Caso contrario, perderán el carácter de
elitistas, viéndose forzados a competir junto al resto de los individuos menos aptos
nuevamente y, consecuentemente, brindando a éstos últimos la posibilidad de
mejorar con mayor rapidez en caso de darse el crossover.
Podríamos decir, en principio, que los dos objetivos principales de los
algoritmos genéticos son dos: la exploración y la explotación. Ahora bien, a fin de
lograr ambos objetivos, tendríamos que combinar los métodos hasta ahora
mencionados: la mutación y el elitismo. Y efectivamente, esta acción nos permite no
sólo la convergencia a un máximo óptimo sino también la vasta exploración de
Página 20
múltiples individuos existentes en el caso estudiado, asegurando así que los valores
finales hallados sean lo más cercanos posible al valor ideal.
Página 21