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 < print a 10 a Jorge Baier Aranda, PUC 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 ĺı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 ĺımite de tamaño, el crecimiento se termina cuando el tamaño árbol ha alcanzado el ĺı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 AND OR e AND ne n e ne n NOT s sw AND Descendientes OR AND OR e AND n NOT e ne ne n s sw Jorge Baier Aranda, PUC 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 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. Jorge Baier Aranda, PUC 27
Es el operador más simple de todos. Reproducción 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. Si f es una función estandarizada, entonces g = 1 que asigna valor 1 al individuo de mayor calidad. 1+f es una función normalizada 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) = o i es la salida para una entrada i, Jorge Baier Aranda, PUC 29
entonces podemos medir la calidad de un programa p por f p = i I(p i o i ) 2, donde p i 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. P r(i) = f(i) i f(i) Donde f(i) es la medida de calidad 1 2. Aplicar crossover (si corresponde, probabiĺısticamente). 3. Aplicar mutación (si corresponde, probabiĺı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, probabiĺısticamente). 4. Aplicar mutación (si corresponde, probabiĺı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. Definir el conjunto de terminales. 2. Definir el conjunto de funciones. 3. Definir la función de calidad. 4. 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 Salida 0 0 0.1 0.005 0.2 0.02 0.3 0.045 0.4 0.08 0.5 0.125 0.6 0.18 0.7 0.245 0.8 0.32 0.9 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 600 Prob. cruza 90 % Prob. mutación 5 % Selección Torneo, tamaño 4 Criterio terminación Máximo de generaciones 100 Máximo prof. árbol después de cruza 200 ninguno Máxima prof. mutación 4 Alg. inicialización grow Jorge Baier Aranda, PUC 36
Resultados Las funciones de mejor calidad en las generaciones 0, 1, 2 y 3 se muetran a continuación: f 0 (x) = x 3 f 1 (x) = x 6 3x f 2 (x) = x x(x 4) 1 + 4 x 9(x+1) 5x +x 6 3x f 3 (x) = x2 2 (calidad 0!) Las generaciones posteriores muestran siempre individuos de calidad 0, pero su tamaño crece. Jorge Baier Aranda, PUC 37