Realmente me gusta esta pregunta.
Lo que realmente está preguntando aquí es “¿cómo hacemos un programa que evolucione?”. Por supuesto, como posterchildren for evolution, las personas siempre han estado interesadas en el proceso. Tal vez si pensamos por un segundo en cómo evoluciona la gente, eso nos ayudará …
Aunque existen muchos mecanismos diferentes para la evolución, el que probablemente nos interesa más es la selección natural. Modelar la selección natural es la idea básica detrás de cómo funcionan los algoritmos genéticos. Sin embargo, la selección es solo el acto de decidir entre las cosas; una pregunta más profunda es ¿cómo conseguimos cosas nuevas para decidir? En la evolución, las diferencias surgen a través de mutaciones genéticas aleatorias (quizás no realmente aleatorias, sino aleatorias).
Entonces tenemos dos pasos:
1. ajustar al azar el programa
2. introducir un proceso de selección
¿Pero cómo seleccionamos? Tenemos que tener algún criterio de selección. En la vida, la selección se trata de la capacidad de producir descendencia. Consideramos una especie “seleccionada” si su descendencia vive para producir más descendencia.
Quizás deberíamos diseñar nuestro programa en la misma línea. Queremos diseñar un programa que creará nuevos programas que crearán nuevos programas … etc.
Para hacer esto, debemos introducir la aleatoriedad, ya que ese es el método de mejora que podemos encontrar en la naturaleza. Al final del día, la aleatoriedad es el “motor del progreso” detrás de la evolución.
Por supuesto, eventualmente obtendremos un mal programa (dependiendo de la intensidad del ajuste, incluso el segundo programa puede ser inutilizable). La solución de Natures es intentarlo de nuevo. Implementar esto solo requiere un cambio en el programa inicial. En lugar de que nuestro programa cree una nueva versión de sí mismo y se detenga, debemos escribir nuestro primer programa para ajustarlo y luego volver a ejecutarlo. Esto evitará que nuestro programa finalice antes de tiempo.
Esto significa que nuestro segundo programa constará de dos partes: una que ejecuta el hilo original y otra que ejecuta el hilo o hilos modificados. Después de otra iteración, tendríamos un árbol de nuevos hilos con ambos hilos existentes produciendo nuevos hilos.
Esto parece prometedor, pero tenemos algunos problemas nuevos. ¿Qué pasa si uno de nuestros nuevos hilos nunca termina y bloquea todo el proceso? Creo que está bastante claro que tenemos que confiar en algún tipo de gestión de recursos. En la evolución natural, esto se conoce como “muerte” y es el resultado del agotamiento de los recursos (alimentos, ciertos procesos corporales); Este concepto existe en la concurrencia a nivel de hilo. Además, existen otras restricciones sin nuestra ayuda:
1. ciertas operaciones colapsarán el hilo
2. ciertas operaciones colgarán el hilo
Estas mutaciones darían lugar a errores y terminarían prematuramente un hilo antes de que expirara.
La expiración natural parece ser un área con la que debemos ayudar a nuestro programa, pero el “tiempo de espera” no es un tema inusual en concurrencia.
¿Pero por cuánto tiempo dejamos correr nuestros hilos? ¿Cuál es la cantidad de tiempo adecuada para un programa que, con suerte, tendrá capacidades ilimitadas? Es difícil imaginar que podríamos elegir un buen número, pero resulta que tendremos que hacerlo.
Si construimos un mecanismo de retroalimentación en el sistema de sincronización que permitirá tiempo adicional bajo ciertas circunstancias (número de descendientes producidos, fallas), estamos:
1. creando la posibilidad de colgar
2. todavía estableciendo un límite difícil al tener rendimientos decrecientes
No parece un problema terrible; la vida útil no ha cambiado drásticamente en millones de años de evolución en la tierra (el mismo orden de magnitud entre una persona y un T-Rex), por lo que tal vez la naturaleza tampoco tenga un buen mecanismo de retroalimentación.
Entonces, tal vez hemos creado la capacidad de un programa para crear algo más que sí mismo. Una cosa que parece clara es que no hay garantías. Así como la vida casi con seguridad falló en innumerables planetas, no se dice que no tengamos que reiniciar este programa. Sin embargo, podríamos tener una oportunidad decente, con algo de poder de cómputo serio, para que las cosas funcionen.
Una cosa a tener en cuenta es que nuestro objetivo no era producir un programa “inteligente”, sino más bien uno que sea capaz de producir mejores programas. En la naturaleza, la inteligencia es solo una solución para la selección natural (las bacterias funcionan bien sin ella). Lo mejor que podríamos esperar, con un mecanismo de retroalimentación decente, es la biodiversidad entre nuestros hilos. Algunos serán parásitos simples y otros habrán desarrollado formas complejas y sofisticadas de “engañar” al sistema de retroalimentación.
De todos modos, así es como lo haría.