Figura 1: ¿Cómo aproximar la imagen de la izquierda mediante una imagen como la de la derecha? |
El primer paso para formular un problema de
optimización es caracterizar los resultados factibles y el costo
que va a representar la elección de cada resultado. En esta caso,
se tiene una imagen objetivo
a
aproximar, por lo cual cualquier aproximación tentativa forma
parte del espacio de factibilidad. Las aproximaciones solo podrán
ser imágenes construidas mediante la superposición de polígonos
transparentes. Además, en esta caso consideraremos como
aproximaciones válidas solo aquellas imágenes con las mismas
dimensiones de la imagen objetivo.
Se considerará el error el aproximación somo un
error cuadrático medio de los pixeles, esto es
donde
corresponde al pixel en la posición
de la imágen objetivo, y
al pixel en la posición de la aproximación.
Los pasos siguientes en la formulación del
problema corresponden normalmente a agregar restricciones. Si bien
en esta formulación no se considerarán explícitamente
restricciones, en la subsección de casos de uso se analizarán las
distintas limitaciones intrinsecas al computo de la solución.
Un algoritmo genético es un método heurístico inspirado por el proceso de selección natural, y utlizado comunmente en la generación de soluciones de alta calidad a problemas de optimización y busqueda. En el caso del presente trabajo, es utilizado un modelo genético como el mostrado en la Figura 2. En él, un individuo (superviviente) genera un descendiente (nueva generación) afectado por mutaciones. Luego, el individuo que sobrevivirá será aquel que presente un menor error de aproximación, abriendo la posibilidad de ejecutar una nueva iteración.
Cada individuo es caracterizado por su propia cadena de ADN, la cual describe la disposición y el color de los polígonos necesarios para construir la imagen. Así mismo, las mutaciones afectan aleatoria y directamente al ADN del individuo, donde cada mutación válida tiene su propia probabilidad de ocurrencia.
El código del algoritmo fue programado en lenguage python.
Además, con el fin de facilitar la interacción con el usuario, el
programa se implementó en el entorno Jupyter.
El algoritmo genético es implementado en tres clases: Polygon, ADN y History. La función de cada clase se explica a continuación:
En la Figura 3 se muestra el diagrama de clases resultante.
La imagen objetivo utilizada es aquella en la izquierda de la
Figura 1. Se realizaron principalmente tres simulaciones del
algortimo. La primera consideró solo el uso de triángulos y
mutaciones sue solo afectaron triángulos. La segunda admitió el
uso de polígonos con más de tres verticas, y mutaciones que
permitieron variar el número de vértices a un polígono.
Finalmente, la tercera agregó la posibilidad de mutar cada vértice
por separado.
La evolución de las similaciones realizadas se muestra en la
Animación 1. La Animación 1 permite comparar como afecta cada
cambio en la evolución perceptual del algoritmo.
Animación 1:
Resultado obtenido en cada una de las tres pruebas
realizadas. A la izquerda, se muestra el resultado de
aproximar con triángulos. Al centro se muestra el
resultado de agregar polígonos. A la derecha se muestra el
resultado de agregar la mutación de cada vértice. |