Algoritmos genéticos, letra por letra

Un algoritmo genético resuelve problemas imitando a la evolución: crea muchas soluciones al azar, se queda con las mejores, las mezcla y les mete pequeños cambios. Aquí cada solución es una frase y cada letra es un gen.

Mejor frase de la generación 0

Evolución del puntaje

Porcentaje de letras correctas por generación. La diversidad mide qué fracción de la población son frases distintas.

Mejor frase Promedio Diversidad Corrida anterior

Población

Ordenada de mejor a peor. En verde, las letras que ya coinciden; el número es su puntaje (fitness).

Cómo nace un hijo

El mismo proceso en Python

En modo paso a paso se ilumina la línea de cada fase. Los valores de arriba cambian con tus parámetros.


      

¿Qué pasa si...?

Antes de presionar Probar, piensa qué va a pasar. Tu corrida anterior queda en la gráfica como línea punteada para comparar.

Cómo funciona, con calma

Ya viste el algoritmo en acción. Ahora vamos pieza por pieza, con el mismo vocabulario que vas a encontrar en libros y en librerías de Python como DEAP o PyGAD.

La idea en una frase

En lugar de buscar la respuesta directamente, un algoritmo genético mantiene un montón de respuestas imperfectas y las mejora generación tras generación: las mejores tienen más hijos, los hijos mezclan a sus padres y de vez en cuando aparece un cambio al azar.

El vocabulario

Gen
Una pieza de la solución. Aquí, una letra.
Individuo o cromosoma
Una solución completa. Aquí, una frase.
Población
El grupo de individuos que vive en una generación.
Fitness
Un número que dice qué tan buena es una solución. Aquí, cuántas letras coinciden con el objetivo.
Generación
Una vuelta completa del ciclo: evaluar, seleccionar, cruzar, mutar y reemplazar.

El ciclo, paso a paso

  1. Crear la población inicial. Se generan frases con letras al azar. Casi todas son basura, y está bien: lo único que necesitamos al inicio es variedad.
  2. Evaluar. A cada frase se le calcula su fitness. Es la única parte del algoritmo que sabe algo del problema.
  3. Seleccionar padres. Las frases con mejor fitness tienen más probabilidad de reproducirse. No se elige siempre a la mejor, porque la población se volvería una sola frase repetida y dejaría de aprender.
  4. Cruzar. Se combinan dos padres para formar un hijo. Si un padre acertó el principio de la frase y el otro el final, el hijo puede heredar ambos aciertos.
  5. Mutar. Cada letra del hijo tiene una pequeña probabilidad de cambiar al azar. Así aparecen letras que no existían en ningún padre.
  6. Reemplazar. Los hijos forman la nueva generación. Con elitismo, las mejores frases pasan intactas para no perder lo que ya se logró.
  7. Repetir hasta encontrar la solución o agotar el presupuesto de generaciones.

Por qué funciona mejor que adivinar

Adivinar al azar trata cada intento como si fuera el primero: no aprende nada. El algoritmo genético acumula aciertos parciales. Una frase con 3 letras correctas tiene más hijos; algunos conservan esas 3 letras y, con suerte, suman una cuarta. La selección guarda el progreso, el cruce junta avances que surgieron en frases distintas y la mutación aporta material nuevo.

Hay una condición clave: el fitness da crédito parcial. Tener 7 de 10 letras vale más que tener 6. Si solo pudieras saber "acertaste" o "no acertaste", el algoritmo no tendría pistas y sería igual de lento que adivinar.

Exploración contra explotación

Todos los parámetros mueven un mismo balance. Explotar es concentrarse en las mejores soluciones que ya tienes; explorar es probar cosas nuevas. Mucha explotación (torneos grandes, mucha élite, poca mutación) converge rápido, pero puede atorarse en una solución mediocre. Mucha exploración (mutación alta, población grande, selección suave) no se atora, pero avanza despacio. Los retos de arriba son experimentos sobre este balance.

Guía rápida de parámetros

ParámetroPunto de partidaSi lo subes
Población50 a 200Más variedad, pero cada generación tarda más
Mutación1 entre el número de genes (una letra mutada por hijo, en promedio)Más exploración, hasta parecerse a adivinar al azar
Cruce70% a 95%Más mezcla entre soluciones
Tamaño del torneo2 a 5Más presión hacia las mejores, menos variedad
Elitismo1 o 2Menos riesgo de perder a la mejor, menos variedad

La trampa de este ejemplo

Aquí el fitness compara contra la respuesta, así que técnicamente ya la conocemos. Es un ejemplo didáctico para ver el mecanismo. En problemas reales no conoces la solución, pero sí sabes medir qué tan buena es una propuesta: cuánto dura una ruta de reparto, cuántos choques tiene un horario o qué precisión logra un modelo con ciertos hiperparámetros. Cambias la función de fitness y la representación de los genes; el resto del algoritmo queda igual.

Dónde se usan

Brillan cuando el espacio de soluciones es enorme, no hay una fórmula para la mejor respuesta y evaluar una propuesta es relativamente barato. Algunos ejemplos: horarios escolares y turnos de trabajo, rutas de reparto, diseño de piezas y antenas (la NASA usó uno para diseñar la antena de la misión ST5), búsqueda de hiperparámetros en machine learning y estrategias para juegos.

Limitaciones

No garantizan encontrar el óptimo, solo buenas soluciones. Necesitan muchas evaluaciones, lo que duele si evaluar una propuesta cuesta minutos u horas. Y dependen mucho de cómo representes el problema: decidir qué es un gen es la mitad del trabajo.

Todo el algoritmo en Python

Esta versión usa torneo, cruce de un punto y elitismo, igual que los valores por defecto de la simulación. No necesita librerías externas: cópiala, cámbiale la frase y córrela.

Python 3