Introducción
Los algoritmos genéticos (AG) son una clase de algoritmos de optimización inspirados en el proceso de selección natural de la biología. Utilizan técnicas como la herencia, mutación, selección y cruce para generar soluciones a problemas de optimización.
Conceptos Clave
- Población: Un conjunto de posibles soluciones al problema.
- Cromosoma: Representación de una solución.
- Gen: Parte de un cromosoma que representa una característica de la solución.
- Fitness: Una función que evalúa qué tan buena es una solución.
- Selección: Proceso de elegir los mejores cromosomas para reproducirse.
- Cruce (Crossover): Combinar dos cromosomas para producir una nueva solución.
- Mutación: Alterar un gen en un cromosoma para introducir variabilidad.
Pasos de un Algoritmo Genético
- Inicialización: Crear una población inicial de cromosomas.
- Evaluación: Calcular el fitness de cada cromosoma.
- Selección: Seleccionar los cromosomas más aptos para reproducirse.
- Cruce: Combinar pares de cromosomas para producir descendencia.
- Mutación: Aplicar mutaciones aleatorias a algunos genes.
- Reemplazo: Formar una nueva población con los descendientes.
- Terminación: Repetir los pasos 2-6 hasta que se cumpla un criterio de parada (por ejemplo, un número fijo de generaciones o una solución suficientemente buena).
Ejemplo Práctico
Vamos a implementar un algoritmo genético simple para maximizar la función \( f(x) = x^2 \) en el intervalo [0, 31].
Representación del Cromosoma
Usaremos una cadena binaria de 5 bits para representar los valores de \( x \).
Función de Fitness
La función de fitness será simplemente \( f(x) = x^2 \).
Código en Python
import random # Parámetros del algoritmo POPULATION_SIZE = 10 GENES = 5 GENERATIONS = 20 MUTATION_RATE = 0.01 # Función de fitness def fitness(chromosome): x = int(chromosome, 2) return x ** 2 # Crear un cromosoma aleatorio def create_chromosome(): return ''.join(random.choice('01') for _ in range(GENES)) # Crear una población inicial def create_population(): return [create_chromosome() for _ in range(POPULATION_SIZE)] # Selección por torneo def selection(population): tournament = random.sample(population, 3) tournament.sort(key=fitness, reverse=True) return tournament[0] # Cruce de un punto def crossover(parent1, parent2): point = random.randint(1, GENES - 1) child1 = parent1[:point] + parent2[point:] child2 = parent2[:point] + parent1[point:] return child1, child2 # Mutación def mutate(chromosome): chromosome = list(chromosome) for i in range(GENES): if random.random() < MUTATION_RATE: chromosome[i] = '1' if chromosome[i] == '0' else '0' return ''.join(chromosome) # Algoritmo Genético def genetic_algorithm(): population = create_population() for generation in range(GENERATIONS): new_population = [] for _ in range(POPULATION_SIZE // 2): parent1 = selection(population) parent2 = selection(population) child1, child2 = crossover(parent1, parent2) new_population.append(mutate(child1)) new_population.append(mutate(child2)) population = new_population best_chromosome = max(population, key=fitness) print(f"Generation {generation}: Best Fitness = {fitness(best_chromosome)}") return best_chromosome # Ejecutar el algoritmo best_solution = genetic_algorithm() print(f"Best solution: {best_solution} with fitness {fitness(best_solution)}")
Explicación del Código
- Parámetros del Algoritmo: Definimos el tamaño de la población, el número de genes por cromosoma, el número de generaciones y la tasa de mutación.
- Función de Fitness: Calcula el valor de \( x^2 \) para un cromosoma dado.
- Crear Cromosoma y Población: Genera cromosomas aleatorios y una población inicial.
- Selección por Torneo: Selecciona el mejor cromosoma de un subconjunto aleatorio de la población.
- Cruce de un Punto: Combina dos cromosomas en un punto aleatorio.
- Mutación: Cambia aleatoriamente bits en un cromosoma con una probabilidad definida.
- Algoritmo Genético: Ejecuta el ciclo de evaluación, selección, cruce y mutación durante un número fijo de generaciones.
Ejercicio Práctico
Ejercicio 1
Implementa un algoritmo genético para maximizar la función \( f(x, y) = x^2 + y^2 \) en el intervalo [0, 31] para \( x \) y [0, 31] para \( y \). Usa una cadena binaria de 10 bits (5 bits para \( x \) y 5 bits para \( y \)).
Solución
# Función de fitness para dos variables def fitness(chromosome): x = int(chromosome[:5], 2) y = int(chromosome[5:], 2) return x ** 2 + y ** 2 # Crear un cromosoma aleatorio de 10 bits def create_chromosome(): return ''.join(random.choice('01') for _ in range(10)) # Algoritmo Genético def genetic_algorithm(): population = create_population() for generation in range(GENERATIONS): new_population = [] for _ in range(POPULATION_SIZE // 2): parent1 = selection(population) parent2 = selection(population) child1, child2 = crossover(parent1, parent2) new_population.append(mutate(child1)) new_population.append(mutate(child2)) population = new_population best_chromosome = max(population, key=fitness) print(f"Generation {generation}: Best Fitness = {fitness(best_chromosome)}") return best_chromosome # Ejecutar el algoritmo best_solution = genetic_algorithm() x = int(best_solution[:5], 2) y = int(best_solution[5:], 2) print(f"Best solution: x = {x}, y = {y} with fitness {fitness(best_solution)}")
Retroalimentación y Consejos
-
Errores Comunes:
- No ajustar correctamente los parámetros del algoritmo (tamaño de la población, tasa de mutación, etc.).
- No implementar correctamente la función de fitness.
- No manejar adecuadamente los límites de los valores representados por los cromosomas.
-
Consejos:
- Experimenta con diferentes tasas de mutación y tamaños de población para encontrar la configuración óptima.
- Asegúrate de que la función de fitness esté correctamente definida y probada.
- Utiliza técnicas de selección más avanzadas como la selección por ruleta o la selección por ranking para mejorar el rendimiento del algoritmo.
Conclusión
En esta sección, hemos aprendido sobre los algoritmos genéticos, sus componentes clave y cómo implementarlos para resolver problemas de optimización. Hemos visto un ejemplo práctico y un ejercicio para reforzar los conceptos aprendidos. En la siguiente sección, exploraremos otros algoritmos de optimización combinatoria.
Algoritmos Avanzados
Módulo 1: Introducción a los Algoritmos Avanzados
Módulo 2: Algoritmos de Optimización
- Programación Lineal
- Algoritmos de Optimización Combinatoria
- Algoritmos Genéticos
- Optimización de Colonia de Hormigas
Módulo 3: Algoritmos en Grafos
- Representación de Grafos
- Búsqueda en Grafos: BFS y DFS
- Algoritmos de Caminos Mínimos
- Algoritmos de Flujo Máximo
- Algoritmos de Emparejamiento en Grafos
Módulo 4: Algoritmos de Búsqueda y Ordenación
Módulo 5: Algoritmos de Aprendizaje Automático
- Introducción al Aprendizaje Automático
- Algoritmos de Clasificación
- Algoritmos de Regresión
- Redes Neuronales y Deep Learning
- Algoritmos de Clustering
Módulo 6: Casos de Estudio y Aplicaciones
- Optimización en la Industria
- Aplicaciones de Grafos en Redes Sociales
- Búsqueda y Ordenación en Grandes Volúmenes de Datos
- Aplicaciones de Aprendizaje Automático en la Vida Real