Programación Genética Programación Genética consiste en la evolución automática de programas usando ideas basadas en la selección natural (Darwin). No sólo se ha utilizado para generar programas, sino que cualquier otro tipo de soluciones cuya estructura sea similar a la de un programa. Por ejemplo, fórmulas matemáticas, circuitos electrónicos. La evolución se produce en la naturaleza gracias a que: • • • • Existe reproducción entre individuos de una población. Las caracterı́sticas de los individuos afectan su probabilidad de supervivencia. Existe herencia. Existen recursos finitos, que ocasiona competencia. En programación genética se busca que poblaciones de programas evolucionen, transmitiendo su herencia de manera que se adapten mejor al medio. Los mejores individuos tienen mayores probabilidades de reproducirse. La medida de calidad del individuo dependerá del tipo de problema. Jorge Baier Aranda, PUC 17 Una mirada general Un algoritmo de programación genética sigue el siguiente esquema: 1. Genera una población inicial. 2. Mientras no se cumple el criterio de terminación: a) Seleccionar individuos (para reproducción y eliminación), considerando su calidad. b) Combinar y/o variar individuos nuevos. c) Agregar y eliminar individuos. Jorge Baier Aranda, PUC 18 Representación En programación genética, los programas (o individuos) se representan como árboles. Es ası́ como el segmento de código while (a<10) { print(a); a++ } puede representarse por el árbol while < a print 10 Jorge Baier Aranda, PUC a 19 Terminales y Funciones El conjunto de terminales está compuesto por las entradas posibles al individuo, constantes y funciones de aridad 0. El conjunto de funciones está compuesto por los operadores constructos y funciones que pueden componer a un individuo. Ejemplos: Funciones booleanas: AND, OR, NOT, XOR. Funciones aritméticas: PLUS, MINUS, MULT, DIV. Sentencias condicionales: IF, THEN, ELSE, CASE, SWITCH Sentencias para iteraciones: WHILE, FOR, REPEAT..UNTIL El conjunto de terminales y funciones elegidos para resolver un problema particular debe ser, obviamente, suficiente para representar una solución al problema. Por otro lado, no es conveniente usar un número grande de funciones, debido a que esto aumenta el tamaño del espacio de búsqueda (principio de parsimonia). Además es deseable las funciones puedan manejar todos los argumentos que eventualmente podrı́an llegar a tener. Jorge Baier Aranda, PUC 20 Inicialización El primer paso en programación genética consiste en formar la población inicial de individuos. Uno de los parámetros principales para un algoritmo genético es el tamaño máximo de un programa. Este lı́mite puede estar impuesto sobre el número de nodos o sobre la profundidad del árbol. Usualmente, se utilizan dos métodos para generar esta población, el método de grow y el full . Jorge Baier Aranda, PUC 21 El método grow Sea T el conjunto de terminales y F el conjunto de funciones. Se elige aleatoriamente un elemento de F para que conforme la raı́z del árbol. El contenido de los nodos hijos de la raı́z se elige desde F ∪ T . Si el valor elegido es una función, se repite este procedimiento con los hijos. (si el valor elegido es una constante, se termina esa rama del árbol.) Jorge Baier Aranda, PUC 22 El método full El método full hace crecer el árbol en forma similar al método grow , pero siempre se eligen elementos del conjunto de funciones, a menos que el nodo esté a profundidad máxima, en cuyo caso sólo se eligen elementos de T . El resultado de este método son siempre árboles balanceados de profundidad máxima. Si se usa el número de nodos como lı́mite de tamaño, el crecimiento se termina cuando el tamaño árbol ha alcanzado el lı́mite. Jorge Baier Aranda, PUC 23 Operadores Genéticos Los operadores básicos de programación genética son: • Crossover . • Mutación. • Reproducción. Jorge Baier Aranda, PUC 24 Crossover El operador de cruza (crossover ) combina el material genético de individuos intercambiando pedazos dos progenitores para producir dos descendientes. Si los individuos se representan como árboles, se elige al azar un nodo de cada árbol y luego se intercambian los subárboles bajo estos nodos. El intercambio se muestra en la siguiente figura: Jorge Baier Aranda, PUC 25 Padres AND OR e AND AND OR n ne n e NOT ne s sw Descendientes AND OR e AND OR AND ne n s Jorge Baier Aranda, PUC e NOT n ne sw 26 Mutación Actúa sobre un solo individuo, generalmente, uno resultante de un crossover . La mutación actúa con una probabilidad, en general, muy baja y que es un parámetro del algoritmo de programación genética. Un tipo de mutación consiste en escoger en forma aleatoria un nodo del árbol y generar bajo éste otro subárbol (por ejemplo, usando el método grow ). En la siguiente tabla se muestran otros tipos de mutación: Nombre del operador Mutación puntual Permutación Levantamiento Expansión Colapso Mutación de Subárbol Duplicación de Gen Jorge Baier Aranda, PUC Descripción del efecto Un solo nodo es intercambiado por otro de la misma clase Los argumentos de un nodo son permutados Nuevo individuo es generado a partir de un subárbol Un terminal es cambiado por un árbol generado al azar Subárbol es intercambiado por un terminal Subárbol es reemplazado por otro generado al azar. Subárbol es reemplazado por un terminal al azar. 27 Reproducción Es el operador más simple de todos. Se selecciona un individuo y se lo duplica, quedando dos copias dentro de la población. Jorge Baier Aranda, PUC 28 Función de Calidad La calidad es la medida usada por el algoritmo de programación genética durante la evolución simulada para medir qué tan buena es una solución. Una función de calidad se dice estandarizada positiva si es que siempre asigna el valor 0 al individuo que es mejor solución para el problema. Una función de calidad se dice normalizada si es que siempre asigna el valores entre 0 y 1. 1 es una función normalizada Si f es una función estandarizada, entonces g = 1+f que asigna valor 1 al individuo de mayor calidad. Si el objetivo de la PG es aprender una función matemática g, entonces una medida de calidad puede ser el error cuadrático medio. Ası́, I es un conjunto de entradas y g(i) = oi es la salida para una entrada i, Jorge Baier Aranda, PUC 29 entonces podemos medir la calidad de un programa p por fp = X (pi − oi)2, i∈I donde pi es la salida del programa ante la entrada i. La función de calidad depende claramente del tipo de problema. Por ejemplo, en un problema de clasificación en bases de datos, la calidad puede estar medida por el número de ejemplos bien clasificados. Jorge Baier Aranda, PUC 30 Selección La selección es el proceso por el cual se transmiten individuos de una generación a otra. Hay distintos tipos de selección tipos de selección. El primero de ellos se basa en algoritmos genéticos. Para una población de N individuos: 1. Elegir a dos individuos progenitores, privilegiando los con mejor calidad. Esto se hace eligiendo al individuo i con probabilidad. f (i) P P r(i) = i f (i) Donde f (i) es la medida de calidad1 2. Aplicar crossover (si corresponde, probabilı́sticamente). 3. Aplicar mutación (si corresponde, probabilı́sticamente). 1 Nótese que para que esto funcione puede ser necesario normalizar la función antes de hacer este cálculo Jorge Baier Aranda, PUC 31 4. Reproducir. 5. Repetir hasta completar una nueva generación de N individuos. Otra técnica consiste en efectuar torneos: 1. Elegir dos grupos de n individuos aleatoriamente desde la población. 2. Seleccionar al mejor elemento del primer grupo (padre), y al mejor elemento del segundo (madre). 3. Aplicar crossover (si corresponde, probabilı́sticamente). 4. Aplicar mutación (si corresponde, probabilı́sticamente). 5. Los dos nuevos individuos reemplazan a los peores de cada uno de los grupos. Esta última técnica es generalmente preferida por razones de eficiencia. Jorge Baier Aranda, PUC 32 Condición de Término Hasta el momento hemos visto que para hacer evolucionar una población es necesario: • Generar una población inicial. • Seleccionar individuos para producir nuevas generaciones. ¿Cuando nos detenemos? Depende de lo que queramos, pero en general cuando el mejor individuo de la población tiene una calidad aceptable. Jorge Baier Aranda, PUC 33 Resumen En resumen, antes un problema con programación genética, es necesario: 1. 2. 3. 4. Definir el conjunto de terminales. Definir el conjunto de funciones. Definir la función de calidad. Definir parámetros tales como tamaño de la población, tamaño máximo de un individuo, probabilidad de cruza, método de selección y criterio de terminación. Jorge Baier Aranda, PUC 34 Ejemplo Supongamos que se quiere obtener una función matemática que se ajuste al conjunto de 10 ejemplos: Entrada 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 Salida 0 0.005 0.02 0.045 0.08 0.125 0.18 0.245 0.32 0.405 Conjunto de terminales: una variable (para la entrada), y los terminales −5 . . . + 5 Conjunto de funciones: +, -, *, %. Función de calidad: Error cuadrático medio sobre los 10 ejemplos. Jorge Baier Aranda, PUC 35 Otros parámetros: Tamaño Población Prob. cruza Prob. mutación Selección Criterio terminación Máximo de generaciones Máximo prof. árbol después de cruza Máxima prof. mutación Alg. inicialización Jorge Baier Aranda, PUC 600 90 % 5% Torneo, tamaño 4 ninguno 100 200 4 grow 36 Resultados Las funciones de mejor calidad en las generaciones 0, 1, 2 y 3 se muetran a continuación: f0(x) = x 3 f1(x) = x 6 − 3x x f2(x) = x(x − 4) − 1 + x2 f3(x) = 2 4 x − 9(x+1) 5x +x 6−3x (calidad 0!) Las generaciones posteriores muestran siempre individuos de calidad 0, pero su tamaño crece. Jorge Baier Aranda, PUC 37