Cómo aprende un ordenador con jirafas: los algoritmos evolutivos

En el campo hay un árbol con muchas hojas en las ramas altas y unas pocas en las bajas. A su alrededor pastan jirafas con cuellos de distinta altura. Las que llegan a las hojas altas comen bien, las que no llegan pasan hambre. Si esto se repite muchos años, ¿qué jirafas habrá dentro de unas generaciones?
Esa pregunta tiene una respuesta sencilla, y dentro de esa respuesta está la idea entera de los algoritmos evolutivos. Vamos a verlo paso a paso, sin matemáticas y sin necesidad de saber programar.
¿Qué jirafas alcanzan las hojas?
Mira el rebaño. Cada jirafa tiene tres genes (cuello, fémur, tibia), cada uno con un valor del 1 al 5. Cuanto más oscuro el verde de los cuadritos del suelo, más largo el hueso. La jirafa que sume más alcanza más alto.
Pulsa siguiente generación y mira lo que pasa: las tres jirafas con mayor altura total (suma de sus genes) sobreviven y tienen crías. Las tres más bajas no llegan a las hojas, no se reproducen, y son reemplazadas por nuevas crías mezcla de las supervivientes. De vez en cuando, un gen de una cría sale un nivel más alto o más bajo que el de sus padres: eso es la mutación, la pequeña variación que mete novedad en el rebaño.
Pulsa varias veces y observa cómo los cuadritos del suelo se van oscureciendo. Las jirafas se van haciendo más altas. Nadie ha decidido nada. Las hojas y la repetición han hecho el trabajo.
Ningún ingeniero ha programado el cuello largo. El árbol, las hojas, las jirafas y el paso de generaciones han hecho el trabajo. Esa es la idea madre de los algoritmos evolutivos.
¿Qué pasa cuando hay comida para todas? ¿Y cuándo empieza a faltar?
La situación de arriba es la del aprieto. Si en el campo crecen otros árboles más bajos y hojas suficientes para todas las jirafas, las cortas también comen, también tienen crías, y la variedad se mantiene. El rebaño sigue siendo mezcla de cuellos: algunos cortos, algunos medios, algunos largos. Coexisten porque no hay razón para que unos desplacen a los otros.
Pero si el clima cambia y las hojas bajas escasean, las cortas pasan hambre. Cuanto más escasea la comida, más rápido cambia el rebaño. A esto se le llama, sin más vueltas, presión: cuánto aprieta el entorno. Cuanto más aprieta, más rápido se notan los cambios; cuando no aprieta nada, casi no cambian.
Las jirafas no saben que están "evolucionando". Solo nacen, comen lo que pueden, tienen crías parecidas a ellas. El cambio del rebaño es la consecuencia, no el plan.
¿Y si cambiamos el escenario por uno con leopardos?
Imagina ahora una llanura llena de gacelas. En el horizonte aparecen leopardos. ¿Qué gacelas escapan y cuáles caen?
Las que corren más rápido escapan, las lentas no. Si esto se repite, las gacelas rápidas tienen más crías, las lentas no llegan a tenerlas. Generación tras generación, las gacelas se vuelven más rápidas.
El objetivo no lo marca nadie. Es la consecuencia de poder multiplicarse: solo dejan crías los que sobreviven. Cualquier rasgo que ayude a sobrevivir y a tener crías acaba imponiéndose en el rebaño con el tiempo. El entorno no decide nada, solo presiona o favorece: cuando hay recursos de sobra, casi todas se alimentan y se multiplican, y la variedad se mantiene. Cuando los recursos escasean, solo se las arreglan las que tienen mejores rasgos para conseguirlos, y el rebaño cambia rápido.
Y los entornos favorables nunca duran para siempre. Si una población se multiplica sin parar, llega un momento en que ya no hay recursos para todas. Lo que empezó siendo abundancia se vuelve escasez sin que el clima cambie ni aparezcan leopardos: la propia multiplicación la provoca. Por eso la presión, aunque tarde, siempre aparece.
Junto al árbol con hojas altas, el rasgo que se impone es alcanzar arriba: cuello, fémur y tibia sumando. Da igual cómo: una jirafa con el cuello no tan largo pero con las patas larguísimas llega igual que una de cuello enorme y patas normales. En la llanura con leopardos, el rasgo que se impone es la velocidad. Mismo mecanismo, distinto entorno, resultado distinto.
Hay aún más: si todas las gacelas son rapidísimas, los leopardos que sigan vivos serán los que también corran mucho. Y como los leopardos rápidos cazan más, dejan más crías. Es una carrera: gacela y leopardo se empujan a la vez. A esto se le llama, en biología, coevolución. Es lo que pasa cuando dos especies se "tiran del brazo" durante generaciones.
¿Y si lo escribimos con números?
Hasta aquí, una maqueta sencilla, no una clase completa de biología. Nos sirve para entender la idea prestada: variación, selección y repetición. Ahora la traducimos a números.
Las jirafas son fáciles de imaginar, pero los algoritmos no funcionan con jirafas, funcionan con números. Aquí está la traducción: cada jirafa son tres números (cuello, fémur, tibia), uno por gen. Por ejemplo, del 1 al 5:
| Jirafa | Cuello | Fémur | Tibia | ¿Llega a las hojas altas? |
|---|---|---|---|---|
| A | 1 | 2 | 2 | No |
| B | 3 | 3 | 3 | No |
| C | 4 | 3 | 4 | Casi |
| D | 5 | 4 | 5 | Sí |
La altura total que alcanza cada jirafa es la suma de sus tres genes (más la cabeza y el cuerpo, que no varían). El árbol exige un mínimo para llegar a las hojas altas. Las que pasan ese mínimo se alimentan y se reproducen. Las que no, dejan menos crías.
¿Y los hijos? Cada hijo coge cada gen de uno de sus padres al azar. Si la madre tiene cuello=5 y el padre cuello=3, su hijo tendrá cuello=5 o cuello=3 (50-50). Lo mismo con fémur y con tibia.
¿Y los cambios? A veces, al pasar el gen, hay un pequeño error: un cuello=5 se copia como cuello=4, o un fémur=3 sale como fémur=4. Eso es la mutación. Casi nunca pasa, pero cuando pasa, mete variedad nueva.
Cinco cosas que hay que decidir
Para usar este mecanismo en un ordenador hay que preparar el entorno. Eso significa decidir cinco cosas concretas:
- Cómo describir a cada candidato con números (los genes; en las jirafas, cuello, fémur y tibia; en otros problemas, los pesos de una red neuronal, los pasos de un programa, los parámetros de un coche).
- Cómo puntuar a cada candidato (cuánto alcanza la jirafa, cuántas partidas gana, cuánto rinde la solución).
- Cómo combinar dos padres para hacer un hijo (qué genes coge de uno y cuáles del otro).
- Cómo cambiar un gen al azar de vez en cuando (cada cuánto y cuánto).
- Quién sobrevive y quién no (cuánto aprieta la presión, qué porcentaje del rebaño se reemplaza cada vuelta).
Con esas cinco cosas tienes un algoritmo genético. La definición que viene en los libros usa palabras más técnicas (representación, función de aptitud, cruce, mutación, estrategia de selección), pero son exactamente esas cinco cosas.
El detalle interesante: no son mecanismos deterministas. Si lo ejecutas dos veces partiendo del azar, casi seguro no obtienes la misma solución exacta. Tampoco se puede predecir antes de ejecutarlo qué solución concreta saldrá. Pero ambas veces termina en algo bueno, y suele encontrar un buen balance entre las distintas características del problema, incluso cuando son varias y compiten entre sí (más altura pero menos peso, más rápido pero menos resistente, más exacto pero más lento).
¿Cómo lo hace un ordenador?
Una vez tienes las cinco cosas decididas, el ciclo es muy corto:
Empezamos con un montón de candidatos al azar (50, 100, los que sean). Los probamos y le damos una puntuación a cada uno. Nos quedamos con los mejores. Los mezclamos para producir hijos. Cambiamos un poco algún gen de los hijos al azar. Eso es una generación.
Y vuelta a empezar. Repetimos cientos o miles de veces. La puntuación media sube generación tras generación, sin que nadie haya escrito la receta de la solución.
¿Para qué sirve esto de verdad?
Para problemas donde no sabemos la receta pero sí podemos medir si una solución es buena. Ajustar los 22 pesos de una red neuronal para que juegue bien al dilema del prisionero, por ejemplo. No sabemos cuáles son los pesos buenos, pero sí podemos probar muchas combinaciones y quedarnos con las que ganan más partidas. Eso es exactamente lo que hace el juego de entrenar una red neuronal: cada red es una jirafa, sus 22 pesos son sus genes, y la "altura del árbol" es ganar al dilema.
Lo mismo en el modo evolutivo del dilema del prisionero: cada estrategia es una jirafa, su "ADN" son las letras de su comportamiento, y la presión es competir contra las otras estrategias. Generación tras generación, las ganadoras dominan.
¿Por qué se llaman algoritmos evolutivos?
Porque copian lo que ha pasado durante millones de años con las jirafas, las gacelas, las plantas y los virus. No diseñan, dejan que la solución aparezca sola por presión del entorno. La idea es prestada de la naturaleza, pero el ordenador no tiene jirafas dentro, tiene números. Por eso son algoritmos evolutivos, no biología artificial.
Hay un detalle bonito. Cuanto más complicado es el problema, más útiles son estos algoritmos, porque cuando algo es muy complicado nadie sabe la solución exacta, ni siquiera el experto. Pero todos sabemos reconocer una solución buena cuando la vemos. Y eso basta para que el ciclo de probar, quedarse, mezclar y cambiar haga su trabajo.
Para seguir pensando
- ¿Qué pasaría si las crías nunca cambiaran de sus padres, ni un poco?
- ¿Y si la presión fuera tan fuerte que solo sobreviviera la mejor de todas?
- ¿Puede haber varias maneras distintas de ser "buena jirafa" al mismo tiempo?
- ¿Qué pasa cuando dos especies evolucionan a la vez compitiendo entre ellas, como la gacela y el leopardo?
La próxima vez que veas una jirafa con un cuello inverosímil, acuérdate de la idea: probar muchas variantes, quedarse con las que funcionan mejor, mezclarlas, cambiar un poco y repetir. Esa misma lógica ayuda a muchos ordenadores a buscar soluciones cuando no sabemos escribir la receta exacta. No es magia. Es paciencia y selección.
