Recientemente estuve navegando en Reddit y encontré una publicación que enlaza con un ejemplo de "algoritmo genético de JavaScript". Realmente me han fascinado los conceptos de algoritmos genéticos y programación, sin embargo, incluso después de buscar en Google, todavía me siento un poco confundido. ¿Como funciona?
Supongo que los términos del vocabulario me confunden más que cualquier otra cosa. Agradecería ejemplos breves y quizás explicaciones. ¿Solo el concepto de programación genética y cómo podría implementarlo en mis proyectos y por qué?
Respuestas:
Parece que estás hablando de algoritmos genéticos más que de programación genética, pero aquí está mi contribución a tu comprensión.
Puede ser útil pensar en las AG en términos de las partes que las componen.
Entonces, digamos que tienes algún tipo de problema. Lo primero que necesita es una forma de expresar cómo será una solución. Si tuvo un problema de vendedor ambulante con las ciudades A, B, C, D, E, entonces ya sabe cómo sería una solución, una matriz de los nombres de las ciudades [B, C, A, D, E].
Este es el gen .
También conocido como una posible solución al problema. Como menciona Steven A. Lowe, las cadenas de bits son una forma común de codificar genes, pero no es necesario; solo hace que ciertas cosas sean más fáciles. La parte importante es que tiene una manera de representar una solución en esta forma de matriz.
Ahora. ¿Cómo saber si la solución es buena? Necesita una función que pueda decirle y calificar la solución. Entonces, nuevamente para TSP, es posible que tenga una función que mida la distancia recorrida utilizando la ruta [B, C, A, D, E]. La 'calificación' que asigna podría ser simplemente la distancia recorrida, pero en problemas más complicados podría incluir cosas como el costo del viaje y otras cosas.
Esta es la función Fitness .
Entonces, ahora puede tomar una solución potencial y descubrir si es buena. ¿Que sigue?
Luego necesitamos comenzar nuestra primera generación. Entonces generamos un montón de soluciones aleatorias. No importa si son buenos o no. Esta es su población inicial, o semilla. Puedes llamar a esto tu acervo genético.
Entonces, tomas tu reserva genética inicial y aplicas tu función de condición física a todos y les das una calificación. Ahora necesita tomar dos de ellos y hacer una nueva población de ellos, para la próxima generación. ¿A quién seleccionas? Bueno, no desea seleccionar necesariamente solo el más apto del ajuste, eso puede ocasionar algunos problemas. En cambio, necesita una función de selección .
Una forma de seleccionar que es fácil de visualizar es usar una especie de rueda: cada gen es un corte en una rueda, y su puntaje de condición física indica qué tan grande es su corte (cuanto mejor sea la aptitud, mayor será el corte). Coloque un alfiler apuntando a la rueda y gírelo (es decir, genere un número aleatorio). El pin apunta al primer padre. Hazlo de nuevo por el segundo padre.
Ahora, necesitas crear nuevos hijos. Desea combinar los padres para producir una nueva población. Hay varias formas de hacer esto, pero todas se llaman la función de cruce . Puedes dividirlos por la mitad e intercambiar las mitades entre los padres, o hacer algún tipo de intercalación. Esto es muy análogo a los padres de mamíferos que producen nuevos hijos: ambos aportan sus genes al nuevo hijo.
Una vez que tenga esta nueva generación, agrega mutaciones aleatorias, aunque raras , a cada niño. A menudo he visto que las tasas de mutación ocurren en menos del 1%. La función de mutación cambiará aleatoriamente algo en su gen codificado. Si su gen es una cadena de bits, podría intercambiarse un poco, si es un conjunto de ciudades, podría intercambiar 2 ciudades en la lista. La parte importante es que es un hecho relativamente raro y confunde las cosas.
Repita este proceso hasta un número deseado de generaciones, o hasta que su función de aptitud física produzca padres con puntajes de aptitud física consistentemente altos y tenga una solución que es (con suerte, si ha hecho todo bien) óptima.
Eso fue un poco prolijo, así que permítanme resumir con una metáfora:
Espero que esto ayude.
fuente
codificar una solución a un problema como una cadena de bits
escribe una función (llamada función "idoneidad") que evalúa qué tan 'buena' se le da a la solución codificada una cadena de bits; el resultado suele ser un número entre 0 y 1
generar aleatoriamente un montón de estas cadenas de bits y evaluar su aptitud
elija algunos del grupo, generalmente los más aptos, y córtelos por la mitad e intercambie las mitades para hacer algunas cadenas de bits nuevas (cruzadas)
luego, a veces, voltea aleatoriamente algunos bits en algunas de las nuevas cadenas de bits (mutación)
repetir hasta que una buena solución evolucione
por qué hacer esto: algunos problemas tienen enormes espacios de solución posibles, tan grandes que no resulta práctico evaluar todas las posibilidades (cf Problema del vendedor ambulante)
Recomiendo el libro Algoritmos genéticos en búsqueda, optimización y aprendizaje automático
fuente
¡La programación genética es una forma de hacer que la computadora escriba programas para usted!
No piense en "programas" como MS Word, piense en "programas" de la siguiente manera:
Esta función (o programa), por sí misma, no tiene una razón para existir. Estamos buscando soluciones a los problemas. Si necesita encontrar la suma de dos números, simplemente abra la calculadora y haga los cálculos. ¿Qué pasa si alguien le dio la siguiente tabla y le pidió que descubriera la relación entre
result
yx
yy
?Estos datos son sus datos de "entrenamiento". Su computadora usará estos datos para generar algunas hipótesis, luego lo probará con datos reales.
Digamos que no conoce las estadísticas y decide que este problema es demasiado difícil de resolver por sí mismo, por lo que obtendrá la computadora para resolverlo por usted.
Haga que la computadora genere conjeturas al azar
Hace que la computadora genere un millón de respuestas y vea si alguna de ellas se adhiere (¡supongo ... un millón de veces!) El siguiente es un ejemplo de un par de conjeturas:
Puede saberlo o no, pero las funciones o los programas también se pueden representar como árboles, por ejemplo, la segunda función sería:
Puede hacer que se parezca más a un árbol sangrando así (por cierto, busque la notación de pulido inverso y la sintaxis de lisp ... pero comprenderá por qué representamos programas como este en breve):
(
+
está en la parte superior con dos "hojas" de/
yy
./
tiene varios hijos, etc.)Es por eso que lees tanto sobre "árboles" en la programación genética. En cualquier caso, conectamos los valores de
x
yy
en esta función y nos da la respuesta INCORRECTA. No es sorprendente, ya que generamos esto al azar.Ahora decide generar un millón de tales soluciones. Todos ellos están equivocados. Sin embargo, observa que algunas respuestas están más cerca de la respuesta correcta que otras. En otras palabras, algunas soluciones son más "adecuadas" que otras. Tenga en cuenta que la computadora no sabe qué es "correcto" o "incorrecto", por lo que debe proporcionar su propia "función de estado físico". Esta función recibe una solución potencial, los datos de entrenamiento, y es responsable de decirle al sistema GP cuán "adecuada" es esta solución. Como puede imaginar, esta función se ejecuta millones y millones de veces.
Lo que hace diferente a GP
Esto es lo que hace que la programación genética sea diferente de las conjeturas salvajes. Decides hacer otra ronda de millones de conjeturas; sin embargo, lo haces un poco más inteligente. Usted toma el 10% superior de las conjeturas (las que se cerraron a los valores reales) y las hace parte de la segunda generación. También toma muchas de estas soluciones (quizás el mismo 10% ... no lo recuerdo) y decide "mezclarlas".
Elige aleatoriamente dos soluciones, elige aleatoriamente subárboles y comienza a intercambiarlas. Entonces, parte de la solución A termina bajo la solución B y viceversa: simplemente las "cruzó". También tomas algunas soluciones y simplemente las "mutas" ... toma un subárbol y 'atorníllalo' un poco (oye, si la solución es terrible, 'atornillarla sin ninguna razón' en realidad podría mejorarla).
Una buena forma de pensar en esto es la siguiente: su mamá y su papá tienen ciertos atributos: color del cabello, estatura, probabilidad de enfermedad, etc. Usted, como niño, hereda diferentes atributos de sus padres. Si tus dos padres fueran atletas olímpicos, también serás un súper atleta, ¿verdad? Bueno, biólogos, sociólogos e incluso historiadores podrían estar en desacuerdo con esta idea, pero los informáticos no están preocupados por la moralidad de la eugenesia aquí. Acaban de ver un "sistema" haciendo un trabajo bastante bueno proporcionando soluciones, por lo que decidieron modelarlo en software.
Si en realidad no coincide con la biología, pero aún así proporciona buenas respuestas ... muchos científicos informáticos dicen colectivamente "lo que sea, y gracias por la terminología". También tenga en cuenta que todos sus hermanos y hermanas y no EXACTAMENTE iguales ... incluso a través de ellos tienen los mismos padres. Cada persona tiene genes que mutan por cualquier razón (por favor, no se lo muestres a un biólogo, el punto es entender la motivación detrás de gran parte de la terminología).
Así que ahora estamos haciendo que la computadora genere millones de programas y midiendo su estado físico. Las mejores soluciones sobreviven hasta la próxima generación. También "mutamos" y cruzamos la "población" (observe cómo se usa el lenguaje de la genética y la biología). Una vez que se crea la segunda generación, la aptitud se mide nuevamente. Dado que esta generación tiene las mejores soluciones de la generación anterior Y cruzamos y mutamos las mejores soluciones (junto con una población mediocre para mantener la diversidad), esta generación debería ser al menos un poco mejor que la generación anterior.
Continuamos esto por un gran número de generaciones. Cada generación (con suerte) ofrece mejores y mejores soluciones, hasta que obtengamos la respuesta correcta. Por ejemplo:
¡Mira esto, es correcto!
(Copié esto de http://en.wikipedia.org/wiki/Genetic_programming , que también tiene una representación gráfica de este árbol)
Retazos
Hay algunos problemas importantes, como cómo decide qué "terminales" (
+, -, *, /, cos, sin, tan
) están disponibles para su sistema GP, cómo escribe la función de estado físico y cómo maneja el sistema programas no sensoriales como(1 + cos)
o(2 / "hello")
(entre muchos otros).Es bastante aburrido desarrollar ecuaciones. Se vuelve más interesante si su conjunto de terminales tiene el siguiente aspecto: (disparar, detectar al enemigo, moverse, ...) y su función de estado físico mide su salud y la cantidad de cadáveres de monstruos marciales.
Escribí la mayor parte de esto de memoria pero esta es la idea básica. Hice algunos GP en mis años universitarios. Definitivamente deberías jugar con eso. No se preocupe por comprender toda la terminología, solo descargue algunos sistemas GP gratuitos, revise algunos ejemplos para tener una idea y cree sus propios ejemplos interesantes (encuentre relaciones entre diferentes conjuntos de datos, intente conectarlo al juego API, etc.)
fuente
Survival of the Fittest: Natural Selection with Windows Forms fue la forma en que me presentaron la programación genética. Es una lectura fácil con código disponible para descargar. La desventaja es que GP requiere un medio para ejecutar el código creado en tiempo de ejecución, y en el momento en que se escribió el artículo, C # no era adecuado para esta tarea. Es por eso que el ejemplo usa CodeDOM para generar, compilar y ejecutar código en tiempo de ejecución, lo que por sí mismo le agrega otra capa de complejidad.
Las cosas han cambiado desde entonces con .NET ahora que tiene una API ExpressionTree propia, lo que probablemente permitiría una implementación GP más elegante en C # que la descrita en el artículo. Pero es lo suficientemente bueno para comprender cómo funciona GP.
Aquí puede descargar un libro electrónico gratuito en GP, que también incluye un ejemplo muy breve de código java que también puede encontrar interesante.
fuente
Los algoritmos genéticos y la programación genética están relacionados, pero son conceptos diferentes.
Los algoritmos genéticos (GA) son algoritmos de búsqueda para problemas complejos de optimización. En un GA, codifica los parámetros de una solución a algún problema en una cadena de bits de "ADN", luego "cría" aleatoriamente estas cadenas de bits: haga que se reproduzcan combinando partes de ellas y aplique "supervivencia del más apto" eliminando todas las cadenas de bits tienes excepto los que son mejores para resolver tu problema.
La programación genética (GP) es aún más complicada: aquí, no representa los programas por su ADN (cadenas de bits), sino por analizar los árboles que cría y selecciona.
fuente