oa.upm.esoa.upm.es/1112/01/pfc_manuel_zaforas.pdf · agradecimientos este proyecto es el colofón a...
TRANSCRIPT
Universidad Politécnica de Madrid
Facultad de Informática
Proyecto fin de carrera
Implementación de un algoritmoevolutivo basado en MOS
Autor: Manuel ZaforasTutores: José María Peña Sánchez
Antonio LaTorre de la Fuente
Madrid, Julio 2008
Implementación de un algoritmo evolutivo basado en MOS
Manuel Zaforas
Madrid, Julio 2008
Tutores:
José María Peña Sánchez ([email protected])
Antonio LaTorre de la Fuente ([email protected])
La composición de este documento se ha realizado con LATEX.
Cita: "La selección natural, es una fuerzasiempre dispuesta a la acción y tan inconmen-surablemente superior a los débiles esfuerzosdel hombre como las obras de la Naturaleza loson a las del Arte."
Charles Darwin.El origen de las especies, capítulo III.
Dedicatoria: Dedicado a la oca del estanque.
Agradecimientos
Este proyecto es el colofón a una etapa de mi vida marcada por muchas personas y experiencias
positivas, que me han llevado a donde ahora estoy y a formarme como ingeniero y como persona.
En primer lugar quiero agradecer a mis padres, ya que en gran medida todo lo que soy y lo bueno
que tengo se lo debo a ellos, que me han apoyado siempre incondicionalmente en todo lo que he hecho.
A mi hermana Carlota por toda la paciencia que tiene conmigo y por haber sido siempre mi amiga.
Gracias sobre todo a Nuria, porque desde que te conocí eres el faro que ilumina mi vida y que me
hace feliz al margen de todo lo demás.
Gracias a todos los compañeros con los que he compartido estudios, prácticas y sufrimientos durante
la carrera, especialmente a Javi, Trevi, Jaime, Alvarito, Rafa, Marí Paz, Jose, Marco, Mariajo, Laura,
Jess, Raquel, Luis, Miguel, Soto, Juanito y todos los que me dejo pero que hemos luchado juntos en este
campo de batalla llamado FI, y de vez en cuando hemos hecho una parada para relajarnos y visitar a los
patos tomando una paella. Gracias también a toda la gente de Delegación, Coleópteros, Alfa y Omega,
Histrión y todos los follones en los que he estado metido en la FI.
Gracias a toda la gente del Laboratorio de Sistemas Operativos del DATSI por todo lo que he apren-
dido con ellos y por lo bien que nos lo hemos pasado en esas largas sobremesas de pueblos y caminos.
Gracias a Fernando Pérez por darme la oportunidad de entrar en el laboratorio y por todo lo que he
aprendido de él. Gracias a los doctorandos: Chuso, Juan, Santi y Alberto por todo lo que saben y la fa-
cilidad con que lo transmiten, estando siempre dispuestos a echar una mano. Gracias también a Alberto,
Germán, Luis y el resto de becarios que compartimos el peso del yugo de nuestras becas rodeados de
neveras y piruletas.
– I –
0. Agradecimientos
Gracias especialmente a los AR: Rojo, Santi, Nacho, Zuazo, Diego, Ato, P. Lorenzo, P. José Manuel,
Chunia y Javi Lorenzo, por esas largas, divertidas e improductivas reuniones en el Rufos o en torno a
unas palomitas quemadas. Gracias también a todos los que siempre están ahí para escaparse al ático
cuando es necesario o para desahogarnos dando patadas a un balón, especialmente a Edu, Ian, Líder,
Pablo, Alex, Sonso (que eres como uno más), Merino, Manza, Chuso, Héctor, Paco, Braci, Luquitas y
todos los demás. Gracias sobre todo al P. Carlos por haber sido un segundo padre para mí.
Gracias a toda la gente del equipo de basket, especialmente a Alfre por todas las cosas que hemos
vivido juntos.
Y por último gracias a Chema y Toni, por toda la paciencia que han tenido conmigo y por todo lo
que he aprendido de ellos, porque sin ellos este proyecto no sería una realidad.
Gracias también a tantos que me dejo en el tintero y en general a todos porque sin duda no habría
llegado hasta aquí sin vosotros.
– II –
Índice
Agradecimientos . . . . . . . . . . . . . . . . . . . . . . . . . . I
Índice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III
Índice de figuras . . . . . . . . . . . . . . . . . . . . . . . . . . IX
Índice de tablas . . . . . . . . . . . . . . . . . . . . . . . . . . XIII
Acrónimos y abreviaturas . . . . . . . . . . . . . . . . . . . . . . XVII
PARTE I INTRODUCCIÓN Y OBJETIVOS
1. Introducción y objetivos . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3. Estructura de la memoria . . . . . . . . . . . . . . . . . . . . 6
PARTE II ESTADO DE LA CUESTIÓN
2. Computación de altas prestaciones con arquitecturas paralelas . . . . . . . . . 9
2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Arquitecturas paralelas: Taxonomía . . . . . . . . . . . . . . . . . 10
– III –
Índice
2.2.1. Multiprocesadores . . . . . . . . . . . . . . . . . . . . 12
2.2.2. Multicomputadores . . . . . . . . . . . . . . . . . . . . 13
2.2.2.1. Clúster . . . . . . . . . . . . . . . . . . . . 14
2.2.2.2. Magerit . . . . . . . . . . . . . . . . . . . . 14
2.3. Topologías y redes de interconexión . . . . . . . . . . . . . . . . . 15
2.3.1. Tecnologías de interconexión . . . . . . . . . . . . . . . . . 16
2.4. Rendimiento en computación paralela . . . . . . . . . . . . . . . . 17
2.4.1. Factor de aceleración: Speedup . . . . . . . . . . . . . . . . 17
2.4.2. Ley de Amdahl . . . . . . . . . . . . . . . . . . . . . 18
2.4.3. Ley de Gustafson . . . . . . . . . . . . . . . . . . . . 19
2.5. Proceso de paralelización: Principios de diseño . . . . . . . . . . . . . 20
2.5.1. Descomposición . . . . . . . . . . . . . . . . . . . . . 21
2.5.2. Asignación . . . . . . . . . . . . . . . . . . . . . . 23
2.5.3. Orquestación . . . . . . . . . . . . . . . . . . . . . . 23
2.5.3.1. Comunicación unicast vs. broadcast . . . . . . . . . . . 23
2.5.3.2. Comunicación estructurada vs. no estructurada . . . . . . . . 24
2.5.3.3. Comunicación estática vs. dinámica . . . . . . . . . . . 25
2.5.3.4. Comunicación síncrona vs. asíncrona . . . . . . . . . . . 25
2.5.4. Despliegue . . . . . . . . . . . . . . . . . . . . . . 25
2.6. Herramientas de programación paralela . . . . . . . . . . . . . . . . 26
2.6.1. HPF . . . . . . . . . . . . . . . . . . . . . . . . 26
2.6.2. MPI . . . . . . . . . . . . . . . . . . . . . . . . 27
2.6.2.1. Funcionamiento de MPI . . . . . . . . . . . . . . . 28
2.6.3. OMP . . . . . . . . . . . . . . . . . . . . . . . . 28
3. Algoritmos evolutivos . . . . . . . . . . . . . . . . . . . . . . . 31
3.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2. Algoritmos genéticos . . . . . . . . . . . . . . . . . . . . . . 33
3.2.1. Esquema de selección . . . . . . . . . . . . . . . . . . . 36
– IV –
Índice
3.2.1.1. Método de la ruleta . . . . . . . . . . . . . . . . 36
3.2.1.2. Método de la ruleta extendido con rangos . . . . . . . . . 37
3.2.1.3. Método de selección por torneo . . . . . . . . . . . . 38
3.2.2. Operador de cruce . . . . . . . . . . . . . . . . . . . . 39
3.2.2.1. Cruce de un punto . . . . . . . . . . . . . . . . . 39
3.2.2.2. Cruce en dos puntos . . . . . . . . . . . . . . . . 39
3.2.2.3. Cruce uniforme . . . . . . . . . . . . . . . . . . 40
3.2.2.4. Cruce aritmético . . . . . . . . . . . . . . . . . 40
3.2.2.5. Cruce cíclico . . . . . . . . . . . . . . . . . . 40
3.2.2.6. Cruce ordenado . . . . . . . . . . . . . . . . . . 41
3.2.3. Operador de mutación . . . . . . . . . . . . . . . . . . . 41
3.2.3.1. Mutación por inversión . . . . . . . . . . . . . . . 41
3.2.3.2. Mutación por intercambio repetido . . . . . . . . . . . 42
3.2.3.3. Mutación uniforme . . . . . . . . . . . . . . . . 42
3.3. Algoritmos EDA . . . . . . . . . . . . . . . . . . . . . . . 42
3.3.1. Heurísticas para el aprendizaje . . . . . . . . . . . . . . . . 44
3.3.1.1. Modelo sin dependencias . . . . . . . . . . . . . . 45
3.3.1.2. Modelos con dependencias bivariantes . . . . . . . . . . 45
3.3.1.3. Modelos con múltiples dependencias . . . . . . . . . . . 45
3.4. Algoritmos evolutivos paralelos . . . . . . . . . . . . . . . . . . 46
3.4.1. Modelos con población global . . . . . . . . . . . . . . . . 46
3.4.1.1. Variante síncrona con maestro-esclavos . . . . . . . . . . 46
3.4.1.2. Variante semisíncrona con maestro-esclavos . . . . . . . . 47
3.4.1.3. Variante asíncrona concurrente . . . . . . . . . . . . . 47
3.4.2. Modelos de islas . . . . . . . . . . . . . . . . . . . . . 47
3.4.2.1. Topologías de interconexión . . . . . . . . . . . . . . 48
3.4.2.2. Sincronización entre islas . . . . . . . . . . . . . . 49
– V –
Índice
PARTE III DISEÑO Y DESARROLLO DE LA SOLUCIÓN
4. Multiple offspring sampling genetic algorithm en GAEDALib . . . . . . . . . 53
4.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . 53
4.2. Diseño y arquitectura de MOS . . . . . . . . . . . . . . . . . . . 54
4.2.1. Aproximación MOS central . . . . . . . . . . . . . . . . . 54
4.2.2. Aproximación MOS autonomic . . . . . . . . . . . . . . . . 57
4.2.3. Relación de MOS y GAEDALib . . . . . . . . . . . . . . . 58
4.3. Clase GAMOSGA . . . . . . . . . . . . . . . . . . . . . . 59
4.4. Técnicas MOS . . . . . . . . . . . . . . . . . . . . . . . . 61
4.4.1. Clase GAMOSTechnique . . . . . . . . . . . . . . . . . . 63
4.4.2. Técnicas MOS GA . . . . . . . . . . . . . . . . . . . . 65
4.4.3. Técnicas MOS EDA . . . . . . . . . . . . . . . . . . . 65
4.4.4. Conjunto de técnicas . . . . . . . . . . . . . . . . . . . 65
4.5. Genomas MOS . . . . . . . . . . . . . . . . . . . . . . . . 66
4.5.1. Clase GAMOSGenome . . . . . . . . . . . . . . . . . . 68
4.6. Conversor MOS . . . . . . . . . . . . . . . . . . . . . . . 69
4.7. Serializador MOS . . . . . . . . . . . . . . . . . . . . . . . 70
PARTE IV ANÁLISIS DE RESULTADOS
5. Análisis de resultados . . . . . . . . . . . . . . . . . . . . . . . 75
5.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . 75
5.2. Resultados con funciones matemáticas . . . . . . . . . . . . . . . . 78
5.2.1. Problema MaxBit . . . . . . . . . . . . . . . . . . . . 78
5.2.1.1. Resultados con Multiple Offspring Sampling (MOS) . . . . . . 79
5.2.2. Problema Royal Road . . . . . . . . . . . . . . . . . . . 83
5.2.2.1. Resultados con MOS . . . . . . . . . . . . . . . . 83
5.2.3. Función Griewank . . . . . . . . . . . . . . . . . . . . 86
– VI –
Índice
5.2.3.1. Resultados con MOS . . . . . . . . . . . . . . . . 86
5.2.4. Función Rastrigin . . . . . . . . . . . . . . . . . . . . 91
5.2.4.1. Resultados con MOS . . . . . . . . . . . . . . . . 91
5.3. Resultados con el TSP . . . . . . . . . . . . . . . . . . . . . 97
5.3.1. Introducción al problema TSP . . . . . . . . . . . . . . . . 97
5.3.2. Variaciones en el número de nodos y en la población . . . . . . . . . 97
5.3.3. Resultados con hibridación de técnicas basadas en GAs . . . . . . . . 103
5.3.3.1. Análisis de la participación y la calidad . . . . . . . . . . 105
5.3.4. Evolución central versus autonómica . . . . . . . . . . . . . . 107
5.3.4.1. Análisis de tiempos . . . . . . . . . . . . . . . . 111
PARTE V CONCLUSIONES Y LÍNEAS FUTURAS
6. Conclusiones y líneas futuras . . . . . . . . . . . . . . . . . . . . 115
6.1. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . 115
6.2. Líneas futuras . . . . . . . . . . . . . . . . . . . . . . . . 116
Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
– VII –
Índice de figuras
2.1. Taxonomía de Flynn . . . . . . . . . . . . . . . . . . . . . 11
2.2. Arquitecturas UMA y NUMA . . . . . . . . . . . . . . . . . . 12
2.3. Arquitectura de un multicomputador . . . . . . . . . . . . . . . . 13
2.4. Magerit. CeSViMa . . . . . . . . . . . . . . . . . . . . . . 14
2.5. Topologías de red . . . . . . . . . . . . . . . . . . . . . . 16
2.6. Ley de Amdahl . . . . . . . . . . . . . . . . . . . . . . . 19
2.7. Etapas del proceso de paralelización . . . . . . . . . . . . . . . . 21
2.8. Impacto del límite de la concurrencia . . . . . . . . . . . . . . . . 22
2.9. Comunicación unicast vs. broadcast . . . . . . . . . . . . . . . . 24
2.10. Comunicación estructurada vs. no estructurada . . . . . . . . . . . . . 24
2.11. Comunicación síncrona vs. asíncrona . . . . . . . . . . . . . . . . 25
2.12. Multithreading con OMP . . . . . . . . . . . . . . . . . . . . 28
3.1. Ejemplo del método de selección de la ruleta . . . . . . . . . . . . . . 37
3.2. Método de la ruleta vs. método de la ruleta con rangos . . . . . . . . . . . 38
3.3. Cruce en un punto . . . . . . . . . . . . . . . . . . . . . . 39
3.4. Cruce en dos puntos . . . . . . . . . . . . . . . . . . . . . 39
3.5. Cruce uniforme . . . . . . . . . . . . . . . . . . . . . . . 40
3.6. Cruce aritmético . . . . . . . . . . . . . . . . . . . . . . . 40
3.7. Cruce cíclico . . . . . . . . . . . . . . . . . . . . . . . . 41
– IX –
Índice de figuras
3.8. Cruce ordenado . . . . . . . . . . . . . . . . . . . . . . . 41
3.9. Operador de mutación por inversión . . . . . . . . . . . . . . . . 41
3.10. Operador de mutación por intercambio . . . . . . . . . . . . . . . 42
3.11. Operador de mutación uniforme . . . . . . . . . . . . . . . . . . 42
3.12. Ejemplo de un modelo gráfico para x = (A,B,C,D) . . . . . . . . . . . 44
3.13. Topologías de islas implementadas en GAEDALib . . . . . . . . . . . . 49
4.1. Visión general del funcionamiento del algoritmo MOS central . . . . . . . . 55
4.2. Diagrama de secuencia del algoritmo MOS . . . . . . . . . . . . . . 56
4.3. Diagrama de secuencia del algoritmo MOS autonomic . . . . . . . . . . 58
4.4. Clases de GAGeneticAlgorithm . . . . . . . . . . . . . . . . . . 59
4.5. Tipos de técnicas MOS . . . . . . . . . . . . . . . . . . . . 63
4.6. Diagrama de clase de genomas MOS . . . . . . . . . . . . . . . . 67
4.7. Funcionamiento del conversor MOS . . . . . . . . . . . . . . . . 69
4.8. Funcionamiento del serializador MOS . . . . . . . . . . . . . . . . 71
5.1. Superficie de la función MaxBit con n = 2 . . . . . . . . . . . . . . 79
5.2. Superficie de la función Griewank con n = 2 y d = 4000 . . . . . . . . . . 86
5.3. Superficie de la función Rastrigin con n = 2, ω = 2π y a = 10 . . . . . . . . 91
5.4. Comparativa de técnicas para el problema Swiss42 . . . . . . . . . . . . 99
5.5. Comparativa de técnicas para el problema Brazil58 . . . . . . . . . . . . 99
5.6. Comparativa de técnicas para el problema Gr120 . . . . . . . . . . . . 100
5.7. Comparativa del fitness con la técnica IntPermOXSIM en Gr120 . . . . . . . 101
5.8. Comparativa del tiempo con la técnica IntPermOXSIM en Gr120 . . . . . . . 102
5.9. Comparativa de los resultados para el TSP con hibridación MOS central . . . . . 104
5.10. Evolución de la participación y la calidad. Combinación de 3 técnicas con el TSP gr120 105
5.11. Evolución de la participación y la calidad para una combinación de 3 técnicas en el
TSP gr120 sin porcentaje mínimo de participación . . . . . . . . . . . . 107
5.12. Comparativa del fitness para el TSP con hibridación MOS autonomic . . . . . . 109
5.13. Comparativa del fitness para el TSP swiss42 con evolución MOS central frente autonomic110
– X –
Índice de figuras
5.14. Comparativa del fitness para el TSP brazil58 con evolución MOS central frente autonomic110
5.15. Comparativa del fitness para el TSP gr120 con evolución MOS central frente autonomic 110
5.16. Comparativa del tiempo para el TSP swiss42 con evolución MOS central frente autonomic111
5.17. Comparativa del tiempo para el TSP brazil58 con evolución MOS central frente auto-
nomic . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.18. Comparativa del tiempo para el TSP gr120 con evolución MOS central frente autonomic 112
– XI –
Índice de tablas
1.1. Alternativas para la configuración de un algoritmo evolutivo . . . . . . . . . 4
2.1. Etapas de la paralelización y sus objetivos . . . . . . . . . . . . . . . 21
2.2. Comparativa de herramientas para programación paralela . . . . . . . . . . 26
3.1. Algunos de los algoritmos evolutivos más representativos . . . . . . . . . . 33
3.2. Ejemplo del cálculo de la probabilidad del método de la ruleta . . . . . . . . . 36
3.3. Ejemplo del cálculo de la probabilidad del método de la ruleta con rangos . . . . . 38
5.1. Técnicas GA definidas . . . . . . . . . . . . . . . . . . . . . 76
5.2. Técnicas EDA definidas . . . . . . . . . . . . . . . . . . . . . 77
5.3. Equivalencia entre identificadores de técnicas . . . . . . . . . . . . . . 77
5.4. Resultados para MaxBit con hibridación MOS central y n = 12 . . . . . . . . 80
5.5. Resultados para MaxBit con hibridación MOS central y n = 30 . . . . . . . . 81
5.6. Resultados para MaxBit con hibridación MOS central y n = 100 . . . . . . . . 82
5.7. Resultados para Royal Road con hibridación MOS central, k = 4, b = 8 y g = 7 . . . 84
5.8. Resumen de fitness para el problema Royal Road con técnicas individuales . . . . 85
5.9. Resumen de mejores fitness para el problema Royal Road con hibridación MOS . . . 85
5.10. Resultados para Griewank con hibridación MOS central, n = 10 y d = 4000 . . . . 87
5.11. Resultados para Griewank con hibridación MOS central, n = 20 y d = 4000 . . . . 88
5.12. Resultados para Griewank con hibridación MOS central, n = 30 y d = 4000 . . . . 89
– XIII –
Índice de tablas
5.13. Resumen de fitness de las peores técnicas para la función Griewank . . . . . . . 90
5.14. Resultados para Rastrigin con hibridación MOS central, n = 5, a = 10 y ω = 2π . . . 92
5.15. Resultados para Rastrigin con hibridación MOS central, n = 20, a = 10 y ω = 2π . . 93
5.16. Resultados para Rastrigin con hibridación MOS central, n = 30, a = 10 y ω = 2π . . 94
5.17. Resumen fitness técnicas individuales para función Rastrigin . . . . . . . . . 95
5.18. Resumen mejores fitness para función Rastrigin con hibridación MOS y n = 20 . . . 96
5.19. Resumen mejores fitness para función Rastrigin con hibridación MOS y n = 30 . . . 96
5.20. Resultados para el TSP con las 7 técnicas evolutivas, 1 nodo y 1000 individuos . . . 98
5.21. Fitness con la técnica IntPermOXSIM en Gr120, variando nodos y población . . . . 100
5.22. Tiempo en segundos con la técnica IntPermOXSIM en Gr120, variando el número de
nodos y de individuos . . . . . . . . . . . . . . . . . . . . . 102
5.23. Resultados para el TSP con hibridación MOS central de técnicas GA . . . . . . 104
5.24. Fitness para el TSP con hibridación MOS autonomic de técnicas Genetic Algorithms (GA)108
– XIV –
Índice de algoritmos
3.1. Algoritmo genético básico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2. Algoritmo Estimation of Distributions Algorithms (EDA) . . . . . . . . . . . . . . . . . 43
– XV –
Acrónimos y abreviaturas
UP Unidad de Proceso
SISD Single Instruction Single Data
MISD Multiple Instruction Single Data
SIMD Single Instruction Multiple Data
MIMD Multiple Instruction Multiple Data
UMA Uniform Memory Access
NUMA Non Uniform Memory Access
cc-NUMA Cache Coherent Non Uniform Memory Access
SMP Symmetric Multi-Processing
CeSViMa Centro de Supercomputación y Visualización de Madrid
UPM Universidad Politécnica de Madrid
SCI Scalable Coherent Interface
IEEE Institute of Electrical and Electronics Engineers
PCI Peripheral Component Interconnect
API Application Programming Interface
– XVII –
0. Acrónimos y abreviaturas
HPF High Performance Fortran
HPF-2 High Performance Fortran versión 2.0
F95 Fortran 95
PVM Parallel Virtual Machine
MPI Message Passing Interface
MPI-2 Message Passing Interface versión 2.0
MPI I/O Message Passing Interface In/out
MPICH Message Passing Interface Chameleon
MPICH2 Message Passing Interface Chameleon versión 2.0
LAM/MPI Local Area Multicomputer Message Passing Interface
OpenMPI Open Message Passing Interface
OMP Open Multi Processing
IBM International Business Machines
IA Inteligencia Artificial
GA Genetic Algorithms
EDA Estimation of Distributions Algorithms
MGP Modelo Gráfico Probabilístico
UMDA Univariate Marginal Distribution Algorithm
PBIL Population Based Incremental Learning
MIMIC Mutual Information Maximization for Input Clustering
COMIT Combining Optimizers with Mutual Information Trees
BMDA Bivariate Marginal Distribution Algorithm
EBNA Estimation of Bayesian Network Algorithm
BOA Bayesian Optimization Algorithm
– XVIII –
0. Acrónimos y abreviaturas
EMNA Estimation of Multivariate Normal Algorithm
EGNA Estimation of Gaussian Network Algorithm
GALib Genetic Algorithm Library
GAEDALib Genetic Algorithm Estimation of Distribution Algorithms Library
MOS Multiple Offspring Sampling
TSP Traveling Salesman Problem
RAND Research and Development
AX Aritmetic Crossover
UC Uniform Crossover
OX Order Crossover
CX Cycle Crossover
EOC Even Odd Crossover
OPC One Point Crossover
TPC Two Points Crossover
BC Blended Crossover
REM Repeated Exchange Mutation
SIM Simple Inversion Mutation
UM Uniform Mutation
GM Gaussian Mutation
SM Swap Mutation
PI Permutation Initializer
SC Simple Comparator
UI Uniform Initializer
PLSC Partial Least Squares Correct
BIC Bayesian Information Criterion
PSO Particle Swarm Optimization
– XIX –
Parte I
Introducción y objetivos
Capítulo 1
Introducción y objetivos
1.1. Introducción
Los algoritmos evolutivos son métodos adaptativos que suelen usarse para solucionar problemas de
búsqueda y optimización no lineales y con espacios de búsqueda que pueden ser muy grandes. Dada
una población de posibles soluciones a un problema concreto, la computación evolutiva expande esta
población con nuevas y mejores soluciones, obtenidas a partir de los individuos de la población anterior.
Este patrón de funcionamiento se inspira en la teoría de la evolución postulada por Darwin en 1859 [6].
Los genes sirven para codificar la representación de un individuo en el que modelizamos una solución al
problema.
Los padres se irán cruzando o combinando de alguna manera y sufriendo alteraciones para generar
los genes de los hijos. El objetivo es conseguir que la población vaya mejorando de generación en genera-
ción produciendo nuevos individuos que mejoren a los anteriores. Siguiendo esta tendencia intentaremos
llegar a una solución válida.
Inicialmente, estos algoritmos fueron considerados desde un punto de vista teórico sin una aplica-
ción muy extendida en el mundo real. Sin embargo, la actividad investigadora en este área ha llegado a
desarrollar todo un modelo teórico y madurar lo suficiente como para poder aplicarse en la solución de
problemas reales en muchos ámbitos. Además, el rápido avance de la tecnología permite disponer cada
vez de forma más sencilla y económica de una gran potencia de cálculo, necesaria para sacar partido a
esta aproximación teórica. Esto ha provocado que los algoritmos evolutivos estén ciertamente en auge,
siendo su uso cada vez más extendido para solucionar problemas en muy diversos campos.
Estas técnicas de optimización están siendo cada vez más utilizadas en diversos escenarios de apli-
cación que se puedan enmarcar dentro del campo de los problemas de búsqueda u optimización de solu-
– 3 –
1. Introducción y objetivos
ciones que crecen de forma no lineal, lo cual incluye campos tan dispares como la química molecular, la
resistencia de materiales, la robótica o la teoría de juegos, entre otros.
El concepto de algoritmo evolutivo engloba toda una familia de técnicas y enfoques teóricos que
tienen en común el mismo patrón de iteración evolutiva y codificación de soluciones como individuos.
Dos de las vertientes más destacables hoy en día son los GA y los algoritmos EDA que, junto con algunas
otras técnicas evolutivas, han conseguido resultados muy interesantes.
El enfoque de los GA fue desarrollado por J.H. Holland en torno a 1975 [15]. Éste es el enfoque más
clásico en el que los padres son seleccionados de una manera arbitraria y recombinados mediante ciertos
operadores de cruce y mutación, dando lugar a una nueva descendencia.
En el enfoque de los algoritmos más avanzados como los EDA los operadores de cruce y mutación
son sustituidos por un modelo probabilístico que es construido a partir de la población actual y a partir
del cual se inferirán los individuos que formarán la siguiente población.
La continua investigación en el área de los algoritmos evolutivos plantea nuevos retos constantemen-
te y propone nuevas técnicas, variaciones o configuraciones, que aportan mejoras a los modelos más
básicos.
1.2. Objetivos
Una de las cuestiones que se nos plantean a la hora de intentar solucionar un problema con un algorit-
mo evolutivo es saber qué aproximaciones y configuraciones son las más adecuadas a nuestro problema.
Como ya hemos visto anteriormente, existen diferentes enfoques de algoritmos evolutivos y, dentro de
éstos, muchas formas de ajustarlos definiendo diferentes operadores, probabilidades, codificaciones y
otros parámetros.
En la tabla 1.1 se presenta un resumen de los elementos a considerar en un algoritmo evolutivo.
Parámetro Opciones
Tipo de algoritmo GA, EDA con redes bayesianas, EDA con redes gaussianas...
Codificación binaria, entera, real...
Operadores cruce, mutación, evaluación, comparación...
Otros parámetros tamaño de la población, probabilidad de cruce y mutación...
Tabla 1.1: Alternativas para la configuración de un algoritmo evolutivo
– 4 –
1.2. Objetivos
La elección y combinación de todos estos elementos supone un problema de optimización en sí mis-
mo. Este proyecto tiene como objetivo la implementación de un nuevo algoritmo evolutivo, denominado
Multiple Offspring Sampling (MOS), que sea capaz de combinar dinámicamente diferentes algoritmos,
codificaciones, operadores y parámetros para llegar a la mejor solución posible de la manera más rápida.
Para poder aplicar este nuevo enfoque basado en una arquitectura de hibridación de algoritmos es
necesario desarrollar un mecanismo para evaluar la calidad de la población durante la ejecución. También
es necesario desarrollar el concepto de “técnica” como combinación de posibles parámetros y permitir
un ajuste dinámico de la participación de las mismas.
En resumen, los objetivos de este proyecto serían los siguientes:
Implementación de un algoritmo con soporte para diferentes técnicas evolutivas.
Desarrollo de la capacidad de evaluación de la calidad de una técnica evolutiva.
• Definición e implementación de estas medidas de calidad.
Orquestación de las técnicas.
• Ajuste dinámico de la participación en base al rendimiento utilizando medidas de calidad.
• Facilitar el diseño y la introducción de nuevas técnicas de recombinación.
Definición de genomas con soporte para múltiples codificaciones.
• Conversión entre codificaciones.
• Serialización de codificaciones.
Con la introducción de todas estas novedades al concepto clásico de hibridación pretendemos mejorar
los resultados obtenidos hasta ahora con algoritmos evolutivos tradicionales o, en el peor de los casos, ser
capaces de detectar la mejor técnica de recombinación de entre todas las disponibles sin un conocimiento
a priori del rendimiento de las mismas. Del mismo modo, pretendemos dar un soporte para el desarrollo
de nuevas investigaciones sobre la materia y la implementación de nuevas técnicas y operadores que
podrán ser incluidos de forma rápida y sencilla.
Estas metodologías a pesar de proponer un método depurado de búsqueda, siguen requiriendo una
cantidad notable de recursos computacionales, concretamente de consumo de procesador. Por ello un
factor muy importante y que va de la mano de los algoritmos evolutivos es el de paralelismo y compu-
tación de altas prestaciones. Además la propia formalización y estructura de los algoritmo evolutivos los
hace muy adecuados para ser paralelizados.
– 5 –
1. Introducción y objetivos
Para demostrar las ventajas de este nuevo modelo lo aplicaremos para solucionar problemas clásicos
en la literatura, como el problema del Traveling Salesman Problem (TSP) y problemas de optimización
de funciones matemáticas clásicas en el mundo de la computación evolutiva.
1.3. Estructura de la memoria
La memoria del proyecto está organizada en seis partes. Tras esta primera parte de introducción y
objetivos del proyecto tenemos la parte dedicada al estado de la cuestión, desglosada en dos capítulos.
El primero está dedicado al estado de la cuestión en lo relativo a computación de altas prestaciones y el
segundo dedicado a la teoría de algoritmos evolutivos.
La siguiente parte, compuesta por los capítulos cuatro y cinco, desglosa al detalle el diseño y desarro-
llo de la solución propuesta para la implementación del algoritmo MOS. En este apartado se expondrán
detalladamente todas las decisiones de diseño adoptadas así como la arquitectura del sistema. En con-
creto, se detallarán especialmente el diseño y funcionamiento de las técnicas MOS, los genomas MOS,
la conversión entre genomas y la serialización de las poblaciones MOS.
En la cuarta parte se hará un detallado análisis de los resultados obtenidos sobre diferentes proble-
mas de búsqueda y optimización para varias combinaciones de parámetros aplicando el algoritmo MOS.
Asimismo, se hará una comparativa de los mejores enfoques para solucionar cada problema. A continua-
ción, en el capítulo séptimo, se presentarán las conclusiones y las futuras líneas de investigación en este
campo. Por último, se incluirá el capítulo de anexos, con información complementaria al desarrollo de
este proyecto.
– 6 –
Parte II
Estado de la cuestión
Capítulo 2
Computación de altas prestaciones conarquitecturas paralelas
En este capítulo se da una visión general de la evolución de las arquitecturas paralelas para compu-
tación de altas prestaciones, centrándonos fundamentalmente en los multicomputadores y su aplicación
en el campo de la computación científica. Se analizará también la necesidad de estos sistemas, las ten-
dencias actuales y las últimas tecnologías para llevar a cabo desarrollos con programación paralela.
2.1. Introducción
Una de las constantes a lo largo de la historia de la informática ha sido la necesidad de incrementar
constantemente la potencia de cálculo disponible. La implementación de algoritmos y aplicaciones cada
vez más complejas y con un coste computacional más alto, ha permitido ir resolviendo problemas más
complejos y llegar a soluciones más precisas manejando grandes volúmenes de datos.
La ejecución de aplicaciones científicas de cálculo intensivo ha puesto de manifiesto la necesidad
de unas arquitecturas hardware de alto rendimiento capaces de satisfacer los fuertes requisitos de estas
aplicaciones.
A pesar de la vertiginosa evolución de las arquitecturas hardware, y de la continua capacidad de la
industria de ofrecer sistemas con mayor capacidad de cálculo, el desarrollo de software con mayores
necesidades de recursos siempre es mucho más rápido. Esta relación no lineal entre el hardware ofrecido
por los fabricantes y las necesidades del software desarrollado en el mundo científico plantea la necesidad
de proponer nuevos modelos capaces de adaptarse a las necesidades de los científicos e ingenieros de una
manera más flexible y económica, que permitan afrontar los nuevos desafíos.
– 9 –
2. Computación de altas prestaciones con arquitecturas paralelas
Frente a la imposibilidad de construir procesadores con capacidad suficiente para llevar a cabo estas
tareas con un coste y en un tiempo razonables, es necesario buscar alternativas. Ante esta perspectiva
la solución más razonable es la introducción de paralelismo. El paralelismo se basa en la ejecución
simultánea en varios procesadores, bien en la misma o en diferentes máquinas. El reparto del trabajo entre
varias instancias permite avanzar mucho más rápido para alcanzar los objetivos y, por tanto, aumentar
notablemente las prestaciones.
El concepto de paralelismo es una revolución en contraposición con la computación secuencial tra-
dicional, ya que permite abaratar de manera espectacular los costes y afrontar retos antes inimaginables,
proporcionando unos sistemas de enormes prestaciones que permiten a los científicos e ingenieros reali-
zar nuevos experimentos y diseños.
Por otro lado, la computación paralela plantea nuevos y complejos retos para los programadores, que
deben de amoldarse a la nueva filosofía y abandonar su concepción de programas secuenciales. Se debe
ser capaz de fragmentar las tareas a realizar de manera adecuada para que éstas puedan ejecutarse de for-
ma paralela. Esto supone una mayor complejidad en el diseño y entran en juego nuevas preocupaciones
que antes no teníamos como el acceso a los datos, la sincronización de los procesos o el intercambio de
información. Todo esto hace muy compleja la programación paralela y es necesario dominar la arquitec-
tura y las herramientas existentes para obtener realmente una ganancia y sacar el máximo partido a las
arquitecturas paralelas.
2.2. Arquitecturas paralelas: Taxonomía
Existen varios modelos de arquitecturas paralelas. Una de las clasificaciones clásicas y generalmente
aceptada es la realizada por el profesor de la Universidad de Stanford Michael J. Flynn en 1972 [11]. Esta
clasificación conocida como “la taxonomía de Flynn” diferencia entre paralelismo de datos y paralelismo
de instrucciones.
El paralelismo de datos se refiere a la posibilidad de realizar una misma operación sobre varios
datos de forma paralela, mientras que el paralelismo de instrucciones hace referencia a la posibilidad de
ejecutar de forma paralela diferentes instrucciones.
La tabla 2.1 muestra las posibles combinaciones al hacer paralelismo de datos y de instrucciones
respecto a las Unidad de Proceso (UP).
– 10 –
2.2. Arquitecturas paralelas: Taxonomía
SISD MISD
Con
jun
to D
ato
s
Conjunto Instrucciones
UP
SISD
Con
jutn
o D
ato
s
Conjunto Instrucciones
UP UP
MISD
SIMD MIMD
Con
jun
to D
ato
s
Conjunto Instrucciones
UP
UP
UP
UP
SIMD
Con
jun
to D
ato
s
Conjunto Instrucciones
UP
UP
UP
UP
UP
UP
UP
UP
MIMD
Figura 2.1: Taxonomía de Flynn
Single Instruction Single Data (SISD): Modelo secuencial tradicional. Las instrucciones se eje-
cutan secuencialmente y cada instrucción se ejecuta sobre un solo dato.
Single Instruction Multiple Data (SIMD): Ejecución secuencial de instrucciones, pero aplicando
cada instrucción a un conjunto de datos de forma paralela. Un ejemplo de esto es Altivec, un
conjunto de instrucciones para coma flotante desarrollado por Apple, IBM y Motorola y que sigue
la filosofía SIMD. Otro ejemplo es la tecnología SSE introducida, también para cálculos en coma
flotante, por Intel en su familia de procesadores Pentium III como extensión para el juego de
instrucciones MMX. Otro campo en el que se ha explotado esta tecnología es el de los procesadores
gráficos, de gran auge en los últimos años.
Multiple Instruction Single Data (MISD): Este modelo tiene poco sentido en computación tra-
dicional. Su desarrollo se limita al campo de la investigación, por ejemplo en los procesadores
sistólicos.
– 11 –
2. Computación de altas prestaciones con arquitecturas paralelas
Multiple Instruction Multiple Data (MIMD): Estas arquitecturas son las más interesantes y las
que implementan la mayoría de computadores paralelos. La idea es tener varios procesadores que
ejecuten instrucciones de forma paralela sobre conjuntos de datos independientes entre sí.
Como hemos comentado anteriormente, las arquitecturas más interesantes y extendidas, en lo que se
refiere a computadores paralelos, son las MIMD. Ahora bien, dentro de este contexto paralelo existen
diferencias sustanciales entre distintas máquinas que lo implementan. La característica más importante a
estudiar es el tipo de mapa de memoria utilizado y cómo accedemos a él.
Inicialmente distinguiremos entre multiprocesadores, si se trata de máquinas con un único espacio
de direcciones, y multicomputadores, si son máquinas con múltiples espacios de direcciones, uno para
cada procesador.
2.2.1. Multiprocesadores
Los multiprocesadores son máquinas con varias unidades de proceso pero una memoria común. El
acceso de todos los procesadores a esta memoria común hace muy compleja la construcción de estas má-
quinas, elevando su coste, pero le da la facilidad al programador de ver un único mapa y poder compartir
la memoria. El acceso a esta memoria se puede realizar fundamentalmente de dos formas:
UMA (Uniform Memory Access): La memoria es compartida y el acceso es uniforme desde todos
los procesadores.
NUMA (Non Uniform Memory Access): Todos los procesadores pueden acceder a toda la memo-
ria, pero no de manera uniforme. Dependiendo de la memoria a la que queramos acceder tendrá
un coste u otro.
UMA NUMA
Bus de conexión
M MM M
UP UP UP UP
UMA
Bus de conexión
M MM M
UP UP UP UP
NUMA
Figura 2.2: Arquitecturas UMA y NUMA
– 12 –
2.2. Arquitecturas paralelas: Taxonomía
Las máquinas Non Uniform Memory Access (NUMA) son más escalables y, generalmente, imple-
mentan complejos algoritmos de coherencia de caches cc-NUMA, cuyo objetivo es minimizar los accesos
a la parte de memoria más costosa de acceder. Algunas máquinas NUMA que han tenido éxito comercial
son el SGI Origin y el Cray T3.
Las máquinas Uniform Memory Access (UMA) son más costosas de implementar y menos esca-
lables. No es habitual que tengán muchos procesadores. En la literatura se usan indistintamente los
términos UMA y Symmetric Multi-Processing (SMP) para referirse a este tipo de arquitecturas. Algu-
nos ejemplos de máquinas UMA son los nodos de máquinas SMP de Sun o HP y, más recientemente,
procesadores comerciales como los Intel Core y los AMD Athlon entre otros.
2.2.2. Multicomputadores
La característica fundamental de los multicomputadores es que son arquitecturas con memoria dis-
tribuida no compartida, de manera que cada procesador tiene su propio mapa de memoria. El conjunto
de procesador, memoria y, en ocasiones, dispositivos de entrada/salida se denomina nodo. Los nodos se
comunicarán entre sí mediante un sistema o red de interconexión a través de paso de mensajes.
Multicomputador
Red de conexión
M
UP
Multicomputador
M
UP
M
UP
M
UP
Figura 2.3: Arquitectura de un multicomputador
Los multicomputadores son más sencillos de construir y más escalables que los multiprocesadores,
pero incorporan la dificultad a la hora de programar aplicaciones, ya que la paralelización la debe realizar
el programador explicitamente mediante paso de mensajes, con toda la complejidad que esto implica.
En muchos casos, uno o varios de los nodos de un multicomputador son, a su vez, multiprocesadores
con varios núcleos.
Algunos ejemplos de multicomputadores son el IBM SP2 con varios nodos, o el Beowulf.
– 13 –
2. Computación de altas prestaciones con arquitecturas paralelas
2.2.2.1. Clúster
Una evolución del concepto de multicomputador son los clúster. Un clúster es un multicomputador
cuyos nodos son computadores de componentes comunes y relativamente baratos y que están conectados
por una red de alta velocidad mediante un switch. El objetivo de un clúster es obtener una máquina de
mayor potencia a partir de computadores no necesariamente muy potentes y a un precio razonable. Al
usar componentes más o menos comunes y habituales en el mercado, el coste de un clúster en relación a
la potencia de cálculo obtenida es bajo.
El modelo de programación de un clúster es necesariamente paso de mensajes entre nodos a través
de la red. Para ello existe una capa de software intermedio, o middleware de comunicaciones, que facilita
esta labor. Un clúster es tremendamente escalable y muy flexible, ya que se le pueden añadir o sustituir
nodos con relativa facilidad. No es necesario que todos los nodos de un clúster tengan la misma arqui-
tectura, ni siquiera es necesario que tengan el mismo sistema operativo. Esto es lo que se denomina un
clúster heterogéneo, frente al concepto de clúster homogéneo, donde sí son iguales todos los nodos.
2.2.2.2. Magerit
Un ejemplo de un clúster lo podemos ver en la figura 2.4. Este clúster, llamado Magerit, es una
máquina perteneciente al Centro de Supercomputación y Visualización de Madrid (CeSViMa), el centro
de supercomputación ubicado en la Universidad Politécnica de Madrid (UPM). Magerit es actualmente
la segunda máquina más potente de España y, en el momento de su instalación, llegó a ser la 34a más
potente del mundo. Es un clúster compuesto por 1204 nodos eServer BladeCenter JS20 y JS21, con dos y
cuatro procesadores IBM PowerPC single-core 970FX de 64 bits a 2’2 GHz. Están conectados mediante
una red Myrinet de alta velocidad. Magerit tiene una potencia pico de 20 Tflops aproximadamente.
Figura 2.4: Magerit. CeSViMa
– 14 –
2.3. Topologías y redes de interconexión
2.3. Topologías y redes de interconexión
Uno de los aspectos clave en computación paralela es la comunicación entre los nodos. Al trabajar de
forma paralela en muchas ocasiones los nodos van a necesitar intercambiarse información y comunicarse
unos con otros para sincronizarse. La necesidad de obtener un alto rendimiento nos obliga a tener muy en
cuenta los tiempos y las latencias de comunicación, ya que podrían suponer un enorme cuello de botella.
Aunque tuviésemos muchos nodos muy potentes, si la red de comunicaciones no es capaz de realizar el
intercambio de información a una velocidad razonable, perderíamos gran parte de nuestra potencia de
cálculo. En la sección 2.3.1 repasaremos algunas de las tecnologías más relevantes para interconexiones
de multicomputadores y multiprocesadores.
Otro aspecto importante, sobre todo en multiprocesadores, es la topología de la red de interconexión
que diseñemos, ya que podemos tener modelos en los que no todos los procesadores estén directamente
conectados entre sí. Esto da lugar a diferentes topologías o formas de colocar y conectar nuestros nodos.
La topología más adecuada dependerá del número de nodos que tengamos, la velocidad de nuestra red y
el tipo de aplicaciones paralelas que vayamos a ejecutar.
En la literatura existen dos conceptos que nos ayudan a definir las topologías de nuestra red:
Anchura de bisección: Número mínimo de conexiones a cortar para obtener dos sistemas iguales.
Ancho de banda en bisección: Ancho de banda a través de los nodos cortados al obtener la
anchura de bisección.
Estos conceptos caracterizan una topología de red y nos permiten estudiar facilmente cual será su
escalabilidad.
Existen multitud de topologías de red. La figura 2.5 recoge algunas de las topologías más clásicas
y que más se implementan en sistemas reales. La topología que elijamos definirá en gran medida las
características de nuestra red y, por lo tanto, influirá de manera significativa en el rendimiento y coste
de nuestro sistema. Para profundizar más en este tema, se puede consultar alguna de las referencias
existentes en la literatura, de entre las que destacan las obras de P. de Miguel [8] y D. Culler[5], más
específica en paralelismo.
– 15 –
2. Computación de altas prestaciones con arquitecturas paralelas
Lineal Malla Anillo Árbol
Cubo 3D Estrella Conexión completa Barras cruzadas
Figura 2.5: Topologías de red
2.3.1. Tecnologías de interconexión
Algunas de las tecnologías de interconexión más relevantes, tanto por la tecnología aportada como
por su éxito comercial, se detallan a continuación, junto con algunas de sus carácterísticas más intere-
santes.
SCI: Scalable Coherent Interface. Estándar IEEE desde 1992, conforma una estructura en anillo de
1, 2 ó 3 dimensiones. Es capaz de mantener la coherencia entre las caches de los procesadores que
conecta, de manera que podría sustituir a un bus de un multiprocesador, aunque su uso en clústers
es sólo como conexión entre nodos. Puede ser la base para implementar una memoria compartida
virtual. Alcanza velocidades de 2500 MB/s obteniendo latencias de 1-2 microsegundos, por lo que
es adecuado para envío de mensajes cortos.
QsNet: QsNet: Quadrics. Evolución de las redes de interconexión de las Meiko Computing Sur-
face, usadas después en las Alphaserver SC. Se compone de un switch (de 16 ó 128 puertos)
y tarjetas adaptadoras PCI que alcanzan hasta 350 MB/s. Se desarrolló una segunda versión en
2003, llamada QsNet II, que alcanza hasta 1.3 GB/s con conexiones bidireccionales y latencias
entre 3 y 5 microsegundos. Internamente usa una topología fat tree.
Myrinet: Myricom. Consiste en un switch de 8 a 256 puertos. Actualmente obtienen latencias de
3 microsegundos y velocidades de 2 GB/s. Está basada en tecnología de fibra óptica, y una de sus
– 16 –
2.4. Rendimiento en computación paralela
principales características es que el procesamiento de las comunicaciones de red se realiza a través
de chips integrados en las tarjetas de red, liberando a la cpu de esta labor. Sus características hacen
que sea altamente escalable, por lo que es la tecnología más utilizada en grandes clústers.
Infiniband: Puede ser usado para conexiones entre subsistemas o entre procesadores. Hoy por
hoy tiene un precio alto, pero es muy versátil ya que tiene especificaciones para conexiones de
cobre y de fibra óptica. Está compuesto por switches de 8 a 124 puertos, que proporcionan 7
microsegundos de latencia en mensajes cortos. Permite diferentes configuraciones y puede llegar
a velocidades de 12 GB/s. Las especificaciones son libres, no está ligado directamente a ninguna
empresa.
2.4. Rendimiento en computación paralela
Cuando paralelizamos un programa o algoritmo para ejecutarlo en un multiprocesador o un multi-
computador nuestro principal objetivo es acelerar su ejecución sacando el máximo partido posible a la
máquina que tenemos por debajo. Existen diferentes medidas que nos ayudan a estudiar el rendimiento
real de nuestro programa, así como las posibilidades de paralelizarlo y obtener un mejor rendimiento.
2.4.1. Factor de aceleración: Speedup
El speedup es la principal medida que nos indica la ganancia que obtenemos con nuestra paraleli-
zación. Se calcula como el cociente entre el tiempo de cálculo en una máquina secuencial y el mismo
cálculo en una máquina paralela con determinado número de procesadores. Obviamente, el speedup de
un programa variará de una máquina paralela a otra, y en función de cómo se haya realizado la paraleli-
zación. Cuanto más alto sea el speedup, más ganancia habremos obtenido con nuestra paralelización.
Speedup =Tsecuencial
Tparalelo(2.1)
Otra medida de interés relacionada con el speedup es la eficiencia. Se define como el cociente entre
el speedup y el número de procesadores en los que ejecutamos, y su valor está comprendido entre 0 y 1.
E f iciencia =Speedup
Nprocesadores(2.2)
Nos interesa que la eficiencia tenga un valor lo más cercano a 1 que sea posible, aunque general-
mente obtendremos un valor menor. En el hipotético caso de que la eficiencia fuera 1, significaría que
la paralelización ha sido total, repartiendo equilibradamente la carga y el tiempo de proceso entre todos
– 17 –
2. Computación de altas prestaciones con arquitecturas paralelas
los procesadores. Llegar a esta situación es casi imposible. La dificultad de repartir equitativamente el
tiempo de proceso estriba en gran medida en cómo sea nuestro algoritmo y lo fácil que sea de paralelizar.
Suele ser muy habitual que haya partes de nuestro algoritmo que no podamos paralelizar de ninguna ma-
nera. Al margen de esto, el hecho de paralelizar siempre supone una mínima carga adicional en concepto
de sincronización y comunicación entre nodos y, en ocasiones, intercambios de datos de un tamaño más
que considerable. Esto hace que nuestra paralelización nunca vaya a ser perfecta, en el sentido de que
frecuentemente obtendremos un rendimiento inferior a 1. En cualquier caso, el objetivo siempre ha de
ser obtener una eficiencia lo más alta posible.
Por otro lado existen algunos casos, bastante atípicos, en los que debido a la propia naturaleza del
algoritmo o a la arquitectura de la máquina que utilicemos, es posible alcanzar una ganancia mayor que
uno. Esta circunstancia se denomina superlinealidad y se da en circunstancias muy concretas.
2.4.2. Ley de Amdahl
En 1967 el ingeniero Gene Amdahl definió una fórmula, conocida como la Ley de Amdahl [1], que
probaba que, a partir de cierto punto, el hecho de agregar más procesadores a una máquina paralela no
producía una mejora significativa en la velocidad de ejecución.
La Ley de Amdahl distingue entre las partes de un programa que son paralelizables (Pparalelizable)
y las que son intrínsecamente secuenciales (Psecuencial) y nunca podremos paralelizar. De manera que
siempre se cumple:
Pparalelizable +Psecuencial = 1 (2.3)
Si sustituimos en la fórmula 2.1 del speedup y simplificamos usando la fórmula 2.3 obtenemos:
Speedup =Pparalelizable +Psecuencial
Psecuencial +PparalelizableNprocesadores
=1
Psecuencial +PparalelizableNprocesadores
(2.4)
La fórmula 2.4 calcula el factor máximo de aceleración en función de las partes de nuestro programa
que son paralelizables.
– 18 –
2.4. Rendimiento en computación paralela
20.00
18.00
16.00
14.00
12.00
10.00
8.00
6.00
4.00
2.00
0.00
Sp
ee
du
p
1 2 4 8 16
32
64
12
8
25
6
51
2
10
24
20
48
40
96
81
92
16
38
4
32
76
8
65
53
6
Número de procesadores
Ley de Amdahl
Porcentaje Paralelización 50% 75% 90% 95%100%
Figura 2.6: Ley de Amdahl
En la figura 2.6 podemos ver gráficamente el speedup que obtendríamos, en función del número
de procesadores, para programas con diferentes porcentajes de código paralelizable. Como se puede
observar claramente, llega un momento en que, para un determinado número de procesadores, no es
posible incrementar más el speedup, ya que éste se estanca. Esto sucede en todos los casos salvo en
el trazo pintado en amarillo que representa problemas que son 100 % paralelizables. En este caso la
relación entre el número de procesadores y el speedup es totalmente lineal (los ejes están escalados) y
crece constantemente.
Existen pocos problemas que sean 100 % paralelizables y que alcancen speedups lineales. Los que lo
son se definen por su naturaleza intrínsecamente paralela en la que el problema se puede descomponer en
tareas totalmente independientes y, generalmente, la solución final es una agregación de las soluciones
parciales. Algún ejemplo de este tipo de problemas es la búsqueda de claves criptográficas por fuerza
bruta o la búsqueda de jugadas en un programa de ajedrez.
2.4.3. Ley de Gustafson
En contraposición a la Ley de Amdahl (sección 2.4.2) el ingeniero y científico John L. Gustafson hizo
una revisión de la misma en 1988, lo que dio lugar a lo que se conoce como la Ley de Gustafson [14].
Guftanson afirmaba que los cálculos de Amdahl eran incorrectos, porque éste consideraba constantes
Psecuencial y Pparalelizable, lo que no es cierto en un programa que ejecuta de forma paralela. Lo correcto
era usar los valores medios en un sistema paralelo, que se definen como P′secuencial y P′paralelizable. Según
esto, un sistema secuencial que sustituyera al paralelo tardaría P′secuencial +P′paralelizableNprocesadores. Por lo
– 19 –
2. Computación de altas prestaciones con arquitecturas paralelas
tanto, deberíamos de reevaluar la fórmula del factor de aceleración definida por Amdahl (fórmula 2.4),
lo que da lugar a la nueva Ley de Gustafson, que es lineal:
Speedup =P′secuencial +P′paralelizableNprocesadores
P′secuencial +P′paralelizable= Nprocesadores +(1−Nprocesadores)P′secuencial (2.5)
En cualquier caso, tanto la Ley de Amdahl como la de Gustafson son simplificaciones. La escala-
bilidad y el factor de aceleración de un sistema paralelo hay que estudiarlos para una implementación
concreta de un algoritmo sobre una máquina dada.
2.5. Proceso de paralelización: Principios de diseño
Dado un programa secuencial, el hecho de paralelizarlo es una tarea muy laboriosa y compleja que
requiere una buena metodología y planificación.
En primer lugar es necesario definir una serie de conceptos que fijen el marco de trabajo del proceso
de paralelización:
Tarea: Es la unidad mínima de cómputo. Se ejecuta siempre secuencialmente y no se puede des-
componer más. Existe concurrencia sólo entre tareas. Pueden existir tareas de grano fino frente a
tareas de grano grueso.
Proceso: Entendemos el proceso como una entidad abstracta que realiza las tareas asignadas a los
procesadores. Los procesos se comunican y sincronizan para realizar las tareas.
Procesador: Máquina física sobre la que se ejecuta un proceso.
Una vez hechas estas definiciones podemos comprender cómo debemos diseñar la paralelización.
Para poder afrontar con una mínimas garantías la labor de paralelización de un programa es necesario
llevar a cabo las siguientes cuatro fases [5]:
Descomposición: Partición de la carga computacional secuencial en tareas.
Asignación: Reparto de las tareas a los procesos.
Orquestación: Coordinación de los accesos necesarios a los datos, la comunicación y sincroniza-
ción entre los procesos.
Despliegue: Asignación entre los procesos y los procesadores.
– 20 –
2.5. Proceso de paralelización: Principios de diseño
La figura 2.7 muestra gráficamente las diferentes etapas del proceso de paralelización y la relación
entre ellas.
Figura 2.7: Etapas del proceso de paralelización
La tabla 2.1 recoge los principales objetivos que se espera conseguir en cada una de estas etapas con
el fin de obtener el mejor rendimiento posible en la paralelización que vamos a realizar:
Etapa Dependencia de la arquitectura Principales objetivos
Descomposición Probablemente no Análisis de la concurrencia.
Asignación Probablemente no Balanceo de carga. Minimizar comunicación.
Orquestación Sí Reducir comunicación para acceso a datos.
Reducir comunicación y sincronización. Pla-
nificar tareas para evitar dependencias.
Despliegue Sí Explotar al máximo la localidad en la topolo-
gía de red.
Tabla 2.1: Etapas de la paralelización y sus objetivos
A continuación comentaremos en profundidad cada una de estas etapas del proceso de paralelización.
2.5.1. Descomposición
Para esta primera fase de descomposición debemos centrarnos inicialmente en el algoritmo. Nuestro
objetivo es analizar las posibilidades de ejecución paralela, centrándonos en obtener el mayor núme-
– 21 –
2. Computación de altas prestaciones con arquitecturas paralelas
ro de tareas, y buscando que sean descomposiciones de grano lo más fino posible. Esto nos dará más
flexibilidad para la agrupación posterior.
Existen dos enfoques a la hora de afrontar esta tarea:
Descomposición del dominio: En primer lugar, determinamos una partición de los datos, para
asociar después unos cálculos sobre estos datos.
Descomposición funcional: Primero descompondremos los cálculos para asignarles depués los
datos que vayan a necesitar.
Debemos tener cuidado en la redundancia tanto en el cómputo como en el almacenamiento de los
datos, ya que en la mayoría de los casos supone una penalización, aunque en ocasiones pueda ser benefi-
cioso. De la misma manera debemos de poner especial énfasis en minimizar, en la medida de lo posible,
las dependencias entre tareas, para evitar sincronizaciones y comunicaciones. Tenemos que procurar
también que las tareas representen cantidades similares de trabajo.
El límite de la concurrencia que podemos obtener viene definido por la ley de Amdahl (sección
2.4.2).
La figura 2.8 muestra un ejemplo de un algoritmo implementado de forma secuencial que podemos
dividir en dos fases. En este ejemplo, la segunda fase depende de los resultados de la primera. Podemos
paralelizar cada fase independientemente y obtener una aceleración casi lineal.
Figura 2.8: Impacto del límite de la concurrencia
– 22 –
2.5. Proceso de paralelización: Principios de diseño
2.5.2. Asignación
La etapa de asignación pretende asignar las tareas, definidas en la fase anterior, a los procesos. De-
bemos buscar equilibrio en la carga de trabajo que asignemos a cada proceso, así como procurar reducir
al máximo la comunicación y sincronización necesarias entre procesos.
A la hora de equilibrar la carga, debemos tener en cuenta algoritmos de planificación por si fuese ne-
cesario equilibrar las funciones. Equilibrar la carga puede ser una tarea muy compleja si hemos definido
pocas tareas, si éstas son de grano gordo o si tienen muchas dependencias entre ellas.
Para reducir la comunicación debemos procurar asignar tareas que ejecutan concurrentemente a di-
ferentes procesos, y asignar tareas que se comunican muy frecuentemente a un mismo proceso.
Fundamentalmente existen dos esquemas de asignación:
Asignación estática: Definimos la asignación de los procesadores al comienzo de la ejecución.
Esto no nos supone muchas sobrecargas más que al comienzo, pero tiene el problema de que el
equilibrado de la carga puede ser malo y no podremos hacer ya nada para corregirlo en tiempo de
ejecución.
Asignación dinámica: La asignación se va ajustando a medida que ejecutamos en función de
la carga de cada nodo del sistema. Permite hacer un balanceo adecuado de la carga, pero nos
introduce retardos debido al coste en tiempo y consumo de procesador que supone hacer esta
asignación dinámica.
2.5.3. Orquestación
El objetivo de la orquestación es estructurar la comunicación entre los procesos, estableciendo la sin-
cronización entre los mismos. También es necesario definir la manera en la que nombramos y manejamos
los datos por parte de los distintos procesos.
En cuanto a la comunicación entre procesos, existen varios patrones de comunicación que la definen,
y que repasaremos en las siguientes subsecciones.
2.5.3.1. Comunicación unicast vs. broadcast
Cuando hablamos de comunicación unicast a nivel de proceso nos referimos a la comunicación que
se establecerá entre un proceso y algunos de los otros procesos que se estén ejecutando en ese momento.
A su vez, estos procesos se comunicarán con otros procesos. La clave de este paradigma unicast frente
al broadcast es que la comunicación se realizará con una parte del resto de procesos, lo que lo hace
– 23 –
2. Computación de altas prestaciones con arquitecturas paralelas
mucho más escalable, aunque en ocasiones más costoso, en contraposición con la comunicación global o
broadcast, donde un proceso se ha de comunicar con todos los demás. Existen mecanismos, generalmente
hardware, que nos permiten sacar un gran rendimiento de la comunicación broadcast, en comparación al
envío unicast de un número similar de mensajes.
(a) Comunicación unicast (b) Comunicación broadcast
Figura 2.9: Comunicación unicast vs. broadcast
2.5.3.2. Comunicación estructurada vs. no estructurada
La comunicación estructurada se refiere a si el patrón de comunicación que implementarán los pro-
cesos responde a una topología o estructura determinada, con el fin de alcanzar la mejor solución. Por el
contrario, cuando usamos comunicación no estructurada la solución que buscamos no depende de la es-
tructura de comunicación entre nodos y sus comunicaciones se realizan en ocasiones de forma aleatoria,
o al menos no siguen una estructura definida.
(a) Comunicación estructurada (b) Comunicación no estructurada
Figura 2.10: Comunicación estructurada vs. no estructurada
– 24 –
2.5. Proceso de paralelización: Principios de diseño
2.5.3.3. Comunicación estática vs. dinámica
Este patrón de comunicación simplemente define si la comunicación será la misma durante toda la
ejecución o irá cambiando en función de las necesidades o reglas que se hayan definido. Una comunica-
ción estática es más fácil de definir, mientras que una comunicación dinámica puede resultar más difícil
de implementar y de equilibrar.
2.5.3.4. Comunicación síncrona vs. asíncrona
Cuando al enviar información de un proceso a otro esperamos a que el receptor reciba el mensaje
estamos hablando de comunicación síncrona, los dos procesos se sincronizan en la comunicación, ya
que uno espera al otro. Si enviamos el mensaje y seguimos ejecutando sin esperar la confirmación de
recepción del otro proceso estamos hablando de comunicación asíncrona.
En el caso de la comunicación asíncrona tiene la ventaja de que los procesos no se quedan bloqueados
en la comunicación, ya que envían la información y siguen ejecutando. Sin embargo, con este mecanismo
no podremos sincronizar unos procesos con otros y, en ocasiones, esto es necesario.
(a) Comunicación síncrona (b) Comunicación asíncrona
Figura 2.11: Comunicación síncrona vs. asíncrona
2.5.4. Despliegue
El objetivo de esta etapa es asignar los procesos a los procesadores en los que ejecutarán. Sólo tiene
sentido cuando paralelicemos en multicomputadores. En ocasiones puede ser necesario migrar procesos
de un procesador a otro, pero esto puede suponer muchos problemas, ya que la memoria es local a cada
procesador y esto puede introducir un coste muy elevado.
– 25 –
2. Computación de altas prestaciones con arquitecturas paralelas
2.6. Herramientas de programación paralela
Existen diferentes herramientas que facilitan la labor del programador a la hora de implementar
una paralelización de un programa. Las diferentes herramientas se orientan a un modelo y arquitectura
diferentes, siendo más adecuada una u otra dependiendo del caso. Estas herramientas consisten en un
Application Programming Interface (API), que nos da una capa de abstracción (de alto o bajo nivel,
según veremos) y que es utilizada por el programador para paralelizar su algoritmo.
En este caso vamos a analizar las herramientas High Performance Fortran (HPF), Message Passing
Interface (MPI) y Open Multi Processing (OMP), ya que son las tres más relevantes en cuanto a su
historia, lo extendido de su uso y filosofía de operación.
La tabla 2.2 muestra una breve comparativa de las principales característias de cada una de estas tres
tecnologías.
HPF MPI OMP
Año primera versión 1993 1994 1997
Versión actual HPF-2 MPI-2 OMP 3.0
Lenguajes soportados Fortran Fortran, C/C++, Java... Fortran, C/C++
Modelo programación Directivas Llamadas biblioteca Directivas
Arquitecturas SIMD, MIMD... SIMD, MIMD... SMP
Uso y repercusión Disminuyendo. Muy extendido. En auge.
Extensiones MPI I/O
Tabla 2.2: Comparativa de herramientas para programación paralela
2.6.1. HPF
Se trata de un lenguaje de programación completo basado en Fortran. Su objetivo es la programación
paralela en máquinas de tipo SIMD con paralelismo de datos. Fue pensado para cálculo intesivo cien-
tífico. Tiene un buen rendimiento y es compatible con Fortran 95 (F95). La mayoría de las llamadas se
hacen en forma de directivas en el programa fuente.
El proceso de compilación es complejo y el rendimiento obtenido es difícil de prever. La primera
versión surgió en 1993 en la Universidad de Rice y su desarrollo hoy en día va por la versión 2.0. Al
estar pensado para programar en lenguaje Fortran su uso no está excesivamente extendido, fuera de los
ámbitos científicos, académicos o de ingeniería.
– 26 –
2.6. Herramientas de programación paralela
2.6.2. MPI
MPI surge como un acuerdo entre empresas, universidades y centros de investigación para definir
una interfaz común de paso de mensajes. MPI se ha convertido en el estándar de facto del modelo de
paso de mensajes orientado a multicomputadores. Una alternativa, anterior a MPI, es Parallel Virtual
Machine (PVM), se trata de una serie de herramientas software que permiten la paralelización. PVM
Apareció en 1989 y fue desarrollado por el Oak Ridge National Laboratory.
La primera versión de MPI apareció en 1994. En 1997 fue lanzada la versión MPI-2, que todavía hoy
sigue vigente y que incorporó la entrada salida paralela con MPI I/O y otras mejoras muy significativas.
En un entorno MPI el programador debe ocuparse de casi todo. MPI únicamente proporciona una
capa de abstracción sobre el hardware, pero dejando al programador la responsabilidad de gestionar la
lógica del intercambio de mensajes.
Existen bindings de MPI para múltiples lenguajes, entre los que se encuentran álgunos de los más
difundidos como Fortran, C, C++, Java o Python. El uso de MPI está extendido en prácticamente todos
los entornos multicomputador tanto a nivel empresarial como en universidades y centros de investigación.
La biblioteca Genetic Algorithm Estimation of Distribution Algorithms Library (GAEDALib), con
la que se ha llevado a cabo este trabajo, se basa en tecnología MPI para soportar el paso de mensajes
entre nodos.
MPI ha triunfado en el sector de los multicomputadores y de la informática general. Esto es debido
al gran esfuerzo que se hizo por parte de las principales empresas y entidades investigadores en ese
momento por conseguir un estándar de facto, pero también se debe a las bondades del diseño de MPI,
que reseñamos a continuación:
Estandarización.
Portabilidad: multiprocesadores, multicomputadores, redes, entornos heterogéneos...
Buenas prestaciones.
Amplia funcionalidad.
Existencia de implementaciones libres.
Una de las características mas atractivas de MPI es que existen varias implementaciones libres dis-
ponibles. Las más destacables son estas dos:
– 27 –
2. Computación de altas prestaciones con arquitecturas paralelas
MPICH: Fue la primera implementación que se llevó a cabo, realizada por el Argonne National
Laboratory y la Universidad del Estado de Mississippi. Hoy en día ya está disponible MPICH2
que implementa MPI-2.
LAM/MPI: Implementado por el Ohio Supercomputing Center, hoy en día se ha combinado con
otros esfuerzos para crear el proyecto OpenMPI que implementa nuevas mejoras.
También existen optimizaciones de alguna implementaciones realizadas por algunos fabricantes. Por
ejemplo la implementación Message Passing Interface Chameleon (MPICH)-GM realizada por la em-
presa Myricom para sus redes Myrinet.
2.6.2.1. Funcionamiento de MPI
Cualquier implementación de MPI consiste en una biblioteca que nos ofrece un interfaz común de
llamadas. Estas llamadas nos permiten realizar todas las acciones necesarias para gestionar el paso de
mensajes. Podemos agrupar las llamadas en cuatro categorías:
1. Llamadas utilizadas para inicializar, administrar y finalizar comunicaciones.
2. Llamadas utilizadas para transferir datos entre un par de procesos.
3. Llamadas para transferir datos entre varios procesos.
4. Llamadas utilizadas para crear tipos de datos definidos por el usuario.
2.6.3. OMP
OMP es un API que permite paralelismo en máquinas con memoria compartida. OMP se basa en una
arquitectura de hilos que realizan tareas paralelas sobre la misma memoria, como muestra la figura 2.12.
Por eso es un requisito que por debajo tengamos memoria compartida aunque cada hilo pueda ejecutarse
en un procesador diferente.
Figura 2.12: Multithreading con OMP
– 28 –
2.6. Herramientas de programación paralela
OMP tiene un modelo de programación basado en directivas que son interpretadas por el compilador.
OMP da una visión de más alto nivel que otras aproximaciones paralelas como MPI, ya que descarga al
programador de la labor de gestionar la lógica de comunicación. La configuración está controlada por
variables de entorno.
OMP surgió en 1997 inicialmente como extensión para el lenguaje fortran y más adelante soportando
también C y C++. Actualmente está disponible la versión 3.0 con múltiples mejoras y extensiones.
El modelo de programación paralela que propone OMP ofrece muchas ventajas al programador:
Simplicidad, no es necesario el paso explícito de mensajes.
El tratamiento y descomposición de los datos es realizado automáticamente por las directivas.
Introducción de paralelismo con muy poco esfuerzo y modificaciones en el código fuente.
Posibilidad de compilación para ejecución secuencial sin modificar el código. Las directivas OMP
son ignoradas por el compilador.
La introducción de directivas no afecta en general a la estructura de nuestros algoritmos, lo que
minimiza la posibilidad de cometer errores.
Posibilidad de hacer paralelismo de grano fino y de grano grueso.
Existen implementaciones de algunos fabricantes muy optimizadas, como la de IBM.
Sin embargo, este modelo también presenta algunos incovenientes:
La concurrencia sólo es eficiente en plataformas SMP.
Necesidad de un compilador específico con soporte para OMP.
La escalabilidad está limitada por la arquitectura de la memoria.
La captura de errores no es fiable.
No es posible sincronizarse entre un subconjunto de hilos.
Obtener una buena optimización requiere conocimientos de la arquitectura.
En resumen, todas estas tecnologías y herramientas vistas a lo largo de este capítulo suponen un
soporte para el desarrollo y ejecución de nuevas aplicaciones de cómputo intensivo. En nuestro caso el
hecho de disponer de este tipo de arquitecturas nos permitirá llevar a cabo la implementación y pruebas
de las aportaciones que propone este proyecto al campo de los algoritmos evolutivos, un área que tradi-
cionalmente ha requerido de gran potencia de cálculo para obtener resultados interesantes en problemas
de gran tamaño.
– 29 –
Capítulo 3
Algoritmos evolutivos
En este capítulo se da una visión general de la teoría de algoritmos evolutivos desarrollada en los
últimos 40 años. Definiremos todos los términos utilizados en este campo. Igualmente, comentaremos
algunos ejemplos de problemas clásicos que se solucionan con este tipo de algoritmos.
Nos centraremos fundamentalmente en los algoritmos genéticos, analizando algunos de los ope-
radores clásicos. En general, definiremos su funcionamiento y la aproximación que hace la biblioteca
GAEDALib [9] al respecto.
También nos interesará conocer la aproximación de los algoritmos EDA y comentaremos brevemente
su estructura basada en redes y métodos de aprendizaje y simulación.
Por último, analizaremos algunos aspectos sobre la ejecución de algoritmos evolutivos paralelos y
sobre la hibridación de múltiples algoritmos evolutivos.
3.1. Introducción
Los algoritmos evolutivos surgen con la necesidad de desarrollar nuevas técnicas avanzadas de op-
timización que sean capaces de resolver problemas complejos de gran magnitud en tiempos razonables.
Surgen dentro del campo de la Inteligencia Artificial (IA) como alternativa de optimización heurística.
Su funcionamiento se basa en una búsqueda guiada pero aún así requieren sistemas de gran capacidad de
cómputo. Su buen rendimiento es posible, en muchos casos, gracias al uso de técnicas de paralelismo,
tal y como se vio en el capítulo 2.
Inspirados en la evolución natural, definida por Charles Darwin en el siglo XIX en su teoría de la
evolución [6], estos algoritmos pretenden superar las limitaciones de los algoritmos de optimización
tradicionales y aumentar el número de problemas resolubles.
– 31 –
3. Algoritmos evolutivos
La aplicación de este enfoque a muchos problemas de optimización en el mundo real ha demostrado
que son una alternativa muy interesante que en muchas ocasiones ha conseguido soluciones de alta
calidad con un alto rendimiento.
Los algoritmos evolutivos suponen un proceso iterativo que consiste en evolucionar o hacer crecer
una población, de manera similar al proceso natural. Los individuos de la población codifican las solu-
ciones a nuestro problema, y son seleccionados en base a su adecuación a la solución óptima buscada,
este comportamiento se inspira en el modelo natural.
Uno de los aspectos más importantes, a la hora de plantearnos solucionar un problema con un algo-
ritmo evolutivo, es encontrar una buena representación para codificar el problema y modelizarlo de la
manera adecuada. Se ha demostrado empíricamente en los últimos años que elegir una representación
adecuada es fundamental para obtener la solución esperada [17].
Del mismo modo, serán decisivos los operadores y parámetros que decidamos utilizar en nuestro
algoritmo para conseguir el éxito.
Los algoritmos evolutivos no dejan de ser una gran familia de algoritmos. Dentro de esta familia
podemos encontrar diferentes aproximaciones que han ido surgiendo a lo largo de la historia y desarrollo
de este campo de investigación. Los pilares de esta taxonomía fueron definidos de forma paralela durante
los años 70 por diferentes científicos e ingenieros que han pasado a la historia como los padres de la
computación evolutiva.
Por citar algún nombre, podemos destacar al profesor de psicología de la Universidad de Míchigan,
J.H. Holland [15], considerado uno de los padres de la computación evolutiva; el profesor de la Uni-
versidad de Dortmund Hans-Paul Schwefel que desarrolló la teoría para la estrategia evolutiva [30]; el
profesor I. Rechenberg de la Universidad Técnica de Berlín que aplicó las estrategias evolutivas al campo
de la aeronáutica [26] y [27]; y, por último, el profesor L.J. Fogel, padre de la programación evolutiva
que también investigó en el campo de la aeronáutica y la cibernética [12].
Algunas de las aproximaciones tradicionales mas relevantes dentro del mundo de los algoritmos
evolutivos las podemos ver en la tabla 3.1. En ocasiones, simplemente difieren en los detalles de la
implementación o en la naturaleza de los problemas a los que se aplican.
– 32 –
3.2. Algoritmos genéticos
Algoritmo Descripción
Algoritmo genético El algoritmo evolutivo más popular. Se suele usar en problemas de optimi-
zación. Representación codificada como una tira de números tradicional-
mente binarios.
Estrategia evolutiva Trabaja con vectores de reales para representar las soluciones.
Programación genética Optimiza una población de programas computacionales de acuerdo a un
fitness determinado por lo bueno que sea un programa en resolver una tarea.
Programación evolutiva Similar a la programación genética pero sin una estructura o representación
fija.
EDA No utiliza operadores de recombinación, intenta aprender un modelo de los
mejores individuos, basándose en redes probabilísticas, que muestrea para
la siguiente generación.
Tabla 3.1: Algunos de los algoritmos evolutivos más representativos
3.2. Algoritmos genéticos
Los algoritmos genéticos son el tipo de algoritmo evolutivo más usual. El concepto de algoritmo
genético, o GA, ha sido extendido a lo largo del tiempo, de manera que ahora hablamos genéricamente
de GA aunque no nos ciñamos a la idea inicial con la que fueron concebidos. Por ejemplo, inicialmente
las soluciones en un GA se codificaban sólo como vectores de números binarios. Hoy en día existen
muchos tipos de representaciones diferentes que están aceptadas dentro de los GA.
Un GA está fuertemente inspirado en la evolución natural. En el mundo real, dada una población ani-
mal, compuesta por individuos, éstos intentan transmitir su material genético a la siguiente generación.
Generalmente, serán los más aptos y adaptados al entorno los que consigan reproducirse. En esta repro-
ducción se combinará el material genético de dos individuos para generar uno o varios descendientes
que se incorporarán a la siguiente generación. Además, en ocasiones la carga genética de los hijos está
sujeta a pequeñas mutaciones fruto de los factores ambientales. A veces estas mutaciones hacen que el
individuo sea más apto para la supervivencia y para poder volver a reproducirse transmitiendo de nuevo
su material genético.
Un algoritmo genético se inspira fuertemente en esta metáfora simplificada, y su objetivo es obtener
el individuo genéticamente más apto tras sucesivas generaciones. Para poder llevar a cabo esta aproxi-
mación debemos considerar los siguientes elementos:
– 33 –
3. Algoritmos evolutivos
Una representación que codifique las posibles soluciones a nuestro problema. Cada individuo de
la población representa una posible solución. Esta información también se conoce como genoma
del individuo, y ha de ser representado de manera que pueda ser manejado por un computador.
Por ejemplo, podemos representar el genoma de un individuo como una tira de bits o de números
reales, aunque también son posibles otras codificaciones más complejas, como listas o árboles.
Una métrica que nos indique cómo de bueno es un individuo. Concretamente, en nuestro caso
nos interesará la comparación con la solución óptima. Este valor es conocido como el fitness
de un individuo y se calculará aplicando el operador de evaluación. El operador de evaluación
matemáticamente se define como: Evaluacion : D→ℜ.
Por poner un ejemplo, en el problema clásico del TSP la medida más usual para el cálculo del
fitness es la longitud del recorrido. En ocasiones nos podrá interesar comparar este valor con el
óptimo, si es que lo conocemos.
Un operador de cruce que, dados un número de individuos, es capaz de cruzar sus genomas con
alguna técnica para generar nuevos hijos. Generalmente, nos encontraremos con el caso de tener
2 padres que, al cruzarse, generen 2 hijos. Esto es lo que se conoce como un cruce sexual, y
matemáticamente se define como: Cruce : D×D→ D×D.
Un proceso de mutación en donde modificamos de manera normalmente aleatoria el genoma de
un individuo. Viene definido por: Mutacion : D→ D.
Unas reglas de selección que, en función del fitness calculado y de una distribución de probabili-
dad, deciden qué individuos de la población total serán los que se reproducirán.
– 34 –
3.2. Algoritmos genéticos
Una vez enumerados todos estos elementos, podemos describir el funcionamiento general de un
algoritmo genético mediante el algoritmo 3.1:
Algoritmo 3.1: Algoritmo genético básico
begin1
Crear población inicial P0.2
Evaluar población inicial P0.3
while no termine do /* Pi converja o límite iteraciones */4
while Seleccionar individuos de la población actual Pi do5
Cruzar con cierta probabilidad obteniendo descendientes.6
Mutar los descendientes con cierta probabilidad.7
Evaluar los nuevos individuos generados.8
Añadir los nuevos individuos en la población auxiliar P′i .9
endw10
Combinar los individuos de Pi y P′i según cierta estrategia para generar Pi+1.11
Evaluar población Pi+1.12
endw13
end14
Este algoritmo general admite algunas variaciones según cómo nos interese implementarlo. Un as-
pecto interesante es la forma en que realizamos el paso 11, ya que existen diferentes enfoques para
combinar las poblaciones. Una alternativa clásica que suele dar buenos resultados y que nos ayuda a
acelerar la convergencia es el elitismo.
El elitismo se basa en suponer que nos interesa recuperar los mejores individuos de la población an-
terior además de los mejores de la nueva población auxiliar generada. Por eso se combinan los individuos
de ambas poblaciones y no nos quedamos simplemente con la nueva población auxiliar, como sería más
acorde al modelo evolutivo natural. Este criterio se basa en la hipótesis de que no siempre los operadores
de cruce y mutación van a generar individuos mejores que sus progenitores. Podría darse el caso de que
fueran similares o incluso peores que éstos y, con vistas a acelerar el proceso de convergencia, puede
que no nos convenga perder soluciones buenas de generaciones anteriores. De este modo, mediante este
mecanismo los vamos conservando a lo largo de la evolución, hasta que realmente manejemos suficientes
individuos que sean mejores. El elitismo es una característica que no está implícita en todos los algorit-
mos genéticos, pero que ha demostrado su utilidad y, por tanto, ha pasado a ser una filosofía de diseño
fundamental en muchos casos.
Otra opción es no aplicar elitismo y que la población auxiliar pase a ser directamente la población de
la siguiente iteración P′i → Pi+1.
– 35 –
3. Algoritmos evolutivos
Volviendo al algoritmo 3.1, podemos observar que se trata de una definición de muy alto nivel, y que
en la ejecución de un algoritmo genético intervienen multitud de parámetros y operadores que dirigen la
búsqueda, y que determinan lo bueno o malo que dicho algoritmo va a resultar al aplicarlo a un problema
concreto. A continuación, vamos a analizar en detalle algunas de estas características.
3.2.1. Esquema de selección
El método de selección de individuos que utilicemos es un factor importante, ya que determina qué
individuos serán los padres de la próxima generación. Si volvemos a la analogía con la evolución natural,
el esquema de selección es lo equivalente a la capacidad de los individuos para conseguir reproducirse y
transmitir su carga genética o no.
Existen diferentes mecanismos para seleccionar individuos, de los cuales repasaremos algunos de los
más utilizados en las secciones subsiguientes:
3.2.1.1. Método de la ruleta
El método de selección de la ruleta (roulette whell selection) es uno de los métodos mas frecuen-
temente utilizados y se basa directamente en las teorías darwinianas [6], premiando los individuos con
mejor fitness y aumentando la probabilidad de que sean éstos los seleccionados para el cruce.
Matemáticamente se define en la ecuación 3.1. Dado un individuo i, si fi es el fitness de este individuo
y N es el tamaño de la población, la probabilidad de que este individuo sea seleccionado es:
pi =fi
∑Nj=1 f j
(3.1)
En la tabla 3.2 se muestra el cálculo del fitness y de las probabilidades para un ejemplo concreto de
5 individuos.
Individuo Fitness Probabilidad
1 6,82 0,31
2 1,11 0,05
3 8,48 0,38
4 2,57 0,12
5 3,08 0,14
Total 22,05 1
Tabla 3.2: Ejemplo del cálculo de la probabilidad del método de la ruleta
– 36 –
3.2. Algoritmos genéticos
Haciendo un símil con una ruleta de casino es como si repartiéramos a los individuos a lo largo de
la ruleta haciendo que los individuos con más fitness tuvieran más posiciones de la ruleta de manera
proporcional a éste. Al lanzar una bola en la ruleta caerá, en la casilla de un individuo, teniendo más
probabilidad de salir los individuos con mejor fitness. En la figura 3.1 se muestran en forma de ruleta los
datos calculados en el ejemplo anterior.
Figura 3.1: Ejemplo del método de selección de la ruleta
3.2.1.2. Método de la ruleta extendido con rangos
El método anterior puede plantear un problema con la escala del fitness, ya que en ocasiones podemos
provocar una rápida convergencia hacia unos pocos individuos si éstos tienen inicialmente un fitness alto
que no está bien escalado.
Para evitar el problema que pueden plantear estos individuos, una posible solución sería introdu-
cir rangos en el método de la ruleta, de manera que produzcamos una repartición más uniforme de la
probabilidad de selección.
El método consiste en ordenar los individuos por fitness y asignarles un rango o etiqueta de 1 a N,
donde N es el tamaño de la población. Matemáticamente se expresa como:
pi =rango( fi)
N(N+1)2
(3.2)
– 37 –
3. Algoritmos evolutivos
La probabilidad se reparte proporcionalmente entre los rangos. Si cogemos un ejemplo más extremo
donde hay individuos con un fitness relativamente alto, podemos observar las diferencias entre el método
de la ruleta y el método de la ruleta con rangos. La figura 3.2 muestra la comparación con el método
simple de la ruleta, y podemos observar que este método es mucho más equitativo.
Individuo Fitness Probabilidad Rango Probabilidad con rangos
1 1 0,01 1 0,1
2 3 0,03 2 0,2
3 7 0,06 3 0,3
4 100 0,9 4 0,4
Total 111 1 10 1
Tabla 3.3: Ejemplo del cálculo de la probabilidad del método de la ruleta con rangos
1%3%
6%
90%
1
2
3
4
(a) Probabilidad con el método de la ruleta
10%
20%
30%
40%
1
2
3
4
(b) Probabilidad con el método de la ruleta con rangos
Figura 3.2: Método de la ruleta vs. método de la ruleta con rangos
3.2.1.3. Método de selección por torneo
En este método, dada una población, se toman n individuos y se elige el que tenga mejor valor de
adecuación. Los individuos pueden atravesar por múltiples rondas de selección en cada generación y, en
función del valor elegido para n, la presión evolutiva ejercida sobre los individuos es mayor o menor.
– 38 –
3.2. Algoritmos genéticos
3.2.2. Operador de cruce
Los algoritmos genéticos fueron descritos inicialmente para utilizar genomas codificados en cadenas
de bits. Sobre este tipo de genomas existen varios operadores de cruce clásicos definidos, pero que en la
mayoría de los casos son extrapolables a genomas basados en vectores de elementos, por ejemplo vecto-
res de enteros o de reales, y que son aplicables en multitud de problemas. En esta sección repasaremos
algunos de los operadores de cruce más representativos en la literatura clásica.
3.2.2.1. Cruce de un punto
En inglés One Point Crossover (OPC). Suponiendo que la codificación del genoma es un vector,
elegimos una posición arbitraria del vector e intercambiamos el material genético tal y como se muestra
en la figura 3.3.
Figura 3.3: Cruce en un punto
3.2.2.2. Cruce en dos puntos
En inglés Two Points Crossover (TPC). Similar al anterior, fruto de las investigaciones de De Jong
en 1975 [16], se eligen dos puntos aleatorios del vector del genoma. La porción del vector que queda
entre estos dos puntos se intercambia en los genomas de los hijos. Podemos ver un ejemplo en la figura
3.4.
Figura 3.4: Cruce en dos puntos
– 39 –
3. Algoritmos evolutivos
3.2.2.3. Cruce uniforme
En inglés Uniform Crossover (UC). En este caso elegimos aleatoriamente por cada gen del hijo si lo
hereda del padre o de la madre. En este cruce sólo se genera un hijo, como se ve en la figura 3.5. Fue
definido en 1991 por Syswerda [33]
Figura 3.5: Cruce uniforme
3.2.2.4. Cruce aritmético
En inglés Aritmetic Crossover (AX). Al igual que en el caso anterior, con este cruce sólo se genera
un hijo. Para calcular el genoma del hijo, como se ve en la figura 3.6, aplicamos un operador binario (por
ejemplo la operación AND) a cada gen de los padres.
Figura 3.6: Cruce aritmético
3.2.2.5. Cruce cíclico
En inglés Cycle Crossover (CX). Este operador de cruce está basado en permutaciones y fue definido
por Oliver en 1987. Siempre genera soluciones válidas para el problema del TSP, dado que no se repiten
los elementos. El funcionamiento está basado en ciclos. Inicialmente se escoge heredar de uno de los
padres una posición de la tira de genes, se comprueban todas las restricciones de manera que se mantenga
la condición de no repetición de elementos y se rellenan los genes necesarios en el hijo para cumplir esas
restricciones. Una vez hecho esto, se inicia un nuevo ciclo donde elegimos de nuevo arbitrariamente
rellenar un gen del padre o de la madre y repetimos hasta rellenar todos los genes. En la figura 3.7 vemos
un ejemplo de cruce cíclico.
– 40 –
3.2. Algoritmos genéticos
Figura 3.7: Cruce cíclico
3.2.2.6. Cruce ordenado
En inglés Order Crossover (OX). Fue propuesto por Davis en 1985. También está basado en permu-
taciones, por lo que los resultados generados son siempre válidos en el problema del TSP. Se basa en
hacer dos cortes en las tiras de genes de los padres y mantener fijo el fragmento central, que es heredado
por los hijos. Después, cada hijo rellena el resto de los genes empezando por la derecha del segundo
corte y en el mismo orden que los genes del padre del que no heredó el fragmento fijo. En la figura 3.8
tenemos un ejemplo de cruce ordenado.
Figura 3.8: Cruce ordenado
3.2.3. Operador de mutación
El operador de mutación debe introducir pequeñas variaciones, casi siempre aleatorias, en la codifi-
cación de los genomas. A continuación detallamos algunos de los más interesantes para nosotros, aunque
se pueden encontrar muchos más detallados en [17].
3.2.3.1. Mutación por inversión
En inglés Simple Inversion Mutation (SIM). Un operador de mutación clásico en las codificaciones
de tiras de bits es el operador inversor que invierte el valor de un bit como se muestra en la figura 3.9.
Figura 3.9: Operador de mutación por inversión
– 41 –
3. Algoritmos evolutivos
3.2.3.2. Mutación por intercambio repetido
En inglés Repeated Exchange Mutation (REM). Definido por Banzhaf en 1990, escoge dos genes del
vector de elementos de forma arbitraria y los intercambia, provocando así una mutación en el genoma del
individuo. Repite esta acción con cada gen de la tira. Las alteraciones que provoca no invalidan nunca el
genoma. Un ejemplo de un único intercambio se muestra en la figura 3.10.
Figura 3.10: Operador de mutación por intercambio
3.2.3.3. Mutación uniforme
En inglés Uniform Mutation (UM). Se utiliza en genomas modelizados como vectores de número
reales. Recorremos todo el vector de reales y para cada posición según cierta probabilidad lo cambiamos
por otro aleatorio (siempre que esté dentro del rango adecuado a nuestro problema), por ejemplo como
se muestra en la figura 3.11 con un rango de reales entre 0,0 y 1,0.
Figura 3.11: Operador de mutación uniforme
3.3. Algoritmos EDA
Los algoritmos EDA son un tipo de algoritmo de la familia de los algoritmos evolutivos, diferentes a
los algoritmos genéticos vistos anteriormente. Los algoritmos EDA también siguen un proceso evolutivo
pero carecen de operadores de cruce y mutación, ya que para generar nuevos individuos utilizan un mo-
delo probabilístico basado en redes que aprende de la población anterior y así genera nuevos individuos.
– 42 –
3.3. Algoritmos EDA
El funcionamiento general de un algoritmo EDA lo podemos ver en el algoritmo 3.2
Algoritmo 3.2: Algoritmo EDA
begin1
Crear población inicial P0.2
Evaluar población inicial P0.3
while no termine do /* Pi converja o límite iteraciones */4
Seleccionar subconjunto de la población actual P̂i ⊂ Pi.5
Estimar la distribución de probabilidad del subconjunto P̂i : pi+1(x), siendo x un individuo6
de la población.
Muestrear la distribución pi+1(x) para generar Pi+1.7
endw8
end9
En el paso 6 es necesario estimar la distribución de probabilidad pi+1(x), siendo x un individuo de
la población. En general, el genoma de un individuo contendrá los valores de un conjunto de variables.
Por tanto x = (x1,x2,x3 . . .) y pi+1(x) = pi+1(x1,x2,x3 . . .). Calcular la distribución de probabilidad con-
junta de (x1,x2,x3 . . .) tiene una complejidad exponencial, en el peor caso (dependencia entre todas las
variables), respecto al número de variables que componen x.
Para evitar un cómputo tan costoso, los algoritmos EDA utilizan un Modelo Gráfico Probabilístico
(MGP). El utilizar un MGP supone reducir el tiempo de cálculo de la distribución conjunta, a cambio
de estimar dicha distribución utilizando un modelo de causalidad condicional entre variables, basado en
un grafo de dependencias/causalidad. Es decir, se simplifican las dependencias entre variables de alguna
forma, de tal manera que el cálculo de la distribución conjunta sea más simple. Como resultado de esta
simplificación obtenemos una aproximación a la distribución conjunta real.
Gráficamente, un MGP es un grafo acíclico dirigido. Cada nodo del grafo representa una variable y
cada arista una dependencia condicional entre variables. La figura 3.12 muestra un ejemplo de un MGP.
– 43 –
3. Algoritmos evolutivos
Figura 3.12: Ejemplo de un modelo gráfico para x = (A,B,C,D)
Teóricamente, para calcular la probabilidad conjunta deberíamos de utilizar la ecuación 3.3.
p(A,B,C,D) = p(A|B,C,D)∗ p(B|C,D)∗ p(C|D)∗ p(D) (3.3)
El desarrollo de esta ecuación supone un cálculo con 15 parámetros. Sin embargo, el MGP de la
figura 3.12 nos indica que podemos considerar independencia condicional entre ciertas variables. Por lo
tanto, podríamos reducir el cálculo de la probabilidad conjunta a la fórmula 3.4 con sólo 8 parámetros.
p(A,B,C,D) = p(A|C,D)∗ p(B|D)∗ p(C)∗ p(D) (3.4)
No podremos aplicar cualquier MGP siempre, ya que éstos dependen directamente del dominio de
las variables del genoma de los individuos y, por tanto, de la codificación que usemos para modelizar las
soluciones de nuestro problema. Si las variables son discretas entonces debemos usar redes bayesianas
[22]. Si por el contrario se trata de variables continuas utilizaremos redes gaussianas [31].
3.3.1. Heurísticas para el aprendizaje
Un aspecto importante en los algoritmos de tipo EDA es cómo generamos la estructura del MGP,
es decir, cómo definimos las dependencias entre variables. Sin ningún conocimiento específico sobre el
problema, la única forma que tenemos de definir estas dependencias es mediante análisis estadísticos.
Este proceso se denomina aprendizaje de la estructura del modelo (structure learning). Existen diversos
métodos para implementar esta fase de aprendizaje.
A continuación analizaremos algunas de las heurísticas más típicas que se utilizan en la fase de
aprendizaje.
– 44 –
3.3. Algoritmos EDA
3.3.1.1. Modelo sin dependencias
Es el modelo más sencillo, en el que suponemos que las variables del genoma no tienen dependencias
entre ellas. Desde el punto de vista gráfico, significa que el grafo no tendrá ninguna arista. Por lo tanto,
la probabilidad conjunta se define como el producto de las probabilidades marginales de cada variable,
como se ve en la ecuación 3.5.
p(x) =n
∏i=1
p(xi) (3.5)
El modelo tiene la ventaja de su sencillez y su bajo coste computacional, pero la suposición de
independencia entre todas las variables puede ser demasiado simplista en algunos problemas.
Algunas de las heurísticas más utilizadas de este modelo en el caso discreto son: Univariate Marginal
Distribution Algorithm (UMDA) [21] y Population Based Incremental Learning (PBIL) [3]. Para el caso
continuo tenemos variantes continuas de los anteriores.
3.3.1.2. Modelos con dependencias bivariantes
Una aproximación un poco más compleja que la anterior consiste en suponer las dependencias exis-
tentes entre dos variables (bivariantes). De este modo se alcanza un buen compromiso entre complejidad
y eficiencia. Este mecanismo define que, como máximo, una variable puede ser dependiente de otra.
En el modelo gráfico esto significa que, como máximo, puede existir una arista saliendo de cada nodo.
Para la generación de estos modelos gráficos es habitual la utilización de algoritmos voraces, que van
añadiendo aristas a un grafo inicialmente disconexo.
En este modelo algunas de las heurísticas más frecuentes, tanto en su versión continua como discreta,
son: Mutual Information Maximization for Input Clustering (MIMIC) [7], Combining Optimizers with
Mutual Information Trees (COMIT) [2] y Bivariate Marginal Distribution Algorithm (BMDA) [24].
3.3.1.3. Modelos con múltiples dependencias
Este tipo de heurísticas tienden a generar modelos más próximos a la realidad, siendo más flexi-
bles a la hora de permitir dependencias entre variables. Esta ventaja tiene en su contra el mayor coste
computacional que suponen a la hora de aprender y simular.
Algún ejemplo concreto para casos discretos son: Estimation of Bayesian Network Algorithm (EB-
NA) [10] y Bayesian Optimization Algorithm (BOA) [23]. Y en el caso continuo: Estimation of Multi-
variate Normal Algorithm (EMNA) [18] y Estimation of Gaussian Network Algorithm (EGNA) [18].
– 45 –
3. Algoritmos evolutivos
3.4. Algoritmos evolutivos paralelos
Los algoritmos evolutivos han pasado de ser un campo dedicado exclusivamente a la investigación a
tener una extendida aplicación en el mundo de la ingeniería, la medicina y otras áreas industriales. Los
algoritmos evolutivos son una solución real a problemas de optimización cotidianos en muchos campos.
Esto ha provocado la necesidad de obtener los mejores resultados posibles en un tiempo razonable.
A la hora de intentar optimizar la eficiencia de un algoritmo evolutivo para que sea lo más atractivo
posible en el mundo real se nos plantean varias cuestiones. El problema de los algoritmos evolutivos es
que la relativa simplicidad de su algoritmo y su naturaleza no determinista, y diferente en cada problema,
no permiten realizar muchas optimizaciones en este sentido con el fin de disminuir la complejidad. Por
otro lado, la forma más evidente e inmediata de obtener mejores resultados es aumentar el tamaño de la
población.
Estas restricciones nos obligan a centrar los intentos de mejora en aumentar la potencia de cómputo
del sistema donde se ejecute el algoritmo. Hoy por hoy la manera más sencilla de conseguir esto es
realizar una paralelización del algoritmo. Además, la estructura de los algoritmos evolutivos hace que
sean relativamente fáciles de paralelizar mediante diferentes enfoques.
A continuación estudiaremos algunas de las aportaciones clásicas, aceptadas como las mejores alter-
nativas para llevar a cabo la paralelización de un algoritmo evolutivo. Para mayor profundización en este
tema se remite al lector a [32].
3.4.1. Modelos con población global
En este modelo de algoritmo evolutivo paralelo, el esquema básico del algoritmo se mantiene. Ten-
dremos, por tanto, una sola población global. Nuestro objetivo será repartir la carga de trabajo entre
varios procesadores. Se han definido tres aproximaciones diferentes [25] para implementar este enfoque.
3.4.1.1. Variante síncrona con maestro-esclavos
Uno de los procesadores adopta el papel de maestro, y el resto el de esclavos. El procesador maestro
realiza los cálculos necesarios para generar los nuevos individuos (en el caso de un algoritmo genético,
por ejemplo, realizar el cruce y la mutación), mientras que los nodos esclavos se encargan de calcular el
fitness de los individuos generados de forma distribuida, es decir, cada esclavo se hace cargo del cálculo
del fitness de una parte de la población generada en cada iteración.
Este enfoque será más o menos inteligente en función de la complejidad del cálculo del fitness,
debido a su naturaleza síncrona. Si el coste computacional del cálculo del fitness es complejo, entonces
– 46 –
3.4. Algoritmos evolutivos paralelos
sí que obtendremos un beneficio notable de repartir este cómputo entre los nodos esclavos. Sin embargo,
si el cálculo del fitness no requiere gran potencia de cálculo, el procesador maestro estará notablemente
más sobrecargado que el resto de los esclavos, lo que provocará un desbalanceo preocupante de la carga,
desperdiciando recursos.
3.4.1.2. Variante semisíncrona con maestro-esclavos
Esta variante es muy similar a la anterior con la diferencia de que el trabajo de los esclavos se estruc-
tura de manera distinta. En lugar de particionar la población entre los procesadores esclavos disponibles,
se particiona en partes más pequeñas. Inicialmente, cada esclavo recibe como carga de trabajo una de es-
tas pequeñas particiones de la población, de la cual calcula su fitness. Una vez los procesadores terminan
los cálculos que les han sido encomendados, solicitan una nueva partición de la que calcular el fitness.
Con esta variante conseguimos un mejor equilibrado de carga entre los esclavos ya que, si algunos de
ellos estuvieran saturados, no supondría un especial retraso del tiempo de cómputo total.
3.4.1.3. Variante asíncrona concurrente
Con las variantes anteriores el mayor problema residía en el reparto no equitativo entre el maestro
y los esclavos. En esta propuesta se pretende solventar este problema eliminando el proceso maestro
haciendo que todos los procesadores trabajen cooperando al mismo nivel. Para esto es necesario mantener
la población global en memoria compartida, de tal modo que cada nodo sea capaz de generar, de manera
independiente, una parte de los nuevos individuos hijos y, también, de calcular su fitness. Para que este
método funcione correctamente es necesario que el esquema de selección tenga en cuenta la existencia
de múltiples hilos de ejecución.
3.4.2. Modelos de islas
Los modelos de islas son un enfoque diferente a los anteriores a la hora de paralelizar un algoritmo
evolutivo. Es posible afrontar este nueva perspectiva por la particular naturaleza de los algoritmos evolu-
tivos y, concretamente, por el hecho de que trabajen con poblaciones de individuos, lo que nos permite
abordar nuevas alternativas a las más tradicionales.
En la paralelización con islas no existe el concepto de población global, sino que cada unión de nodo
y proceso se ve como si fuese una isla con su propia población local. Cada proceso supone una instancia
de nuestro algoritmo evolutivo, que ejecuta de forma secuencial el mismo problema. Cada población local
es inicializada independientemente, de manera que cada isla partirá de poblaciones distintas y obtendrá
– 47 –
3. Algoritmos evolutivos
resultados diferentes. Al final de la ejecución, las poblaciones de cada una de las islas son combinadas
para conformar una población global de la que seleccionaremos el mejor individuo.
Este enfoque tiene la ventaja de que es mucho más resistente a máximos o mínimos locales durante el
proceso de búsqueda. Esto es debido a que cada población es teóricamente independiente de las demás.
Una extensión muy interesante de este modelo supone la introducción del concepto de migración.
La migración entre islas es un artefacto que proporciona el intercambio periódico de individuos entre
islas de acuerdo a una red de interconexión definida. De esta manera, conseguimos introducir variedad
genética en las poblaciones locales y evitamos los estancamientos en las islas.
A la hora de definir este nuevo modelo entran en juego cuatro conceptos a tener en cuenta:
Topología de interconexión de las islas (modelizado como un grafo dirigido).
Periodicidad de la migración.
Cantidad y calidad de los individuos a migrar.
Sincronización entre islas.
3.4.2.1. Topologías de interconexión
Las topologías de interconexión definen qué islas deben migrar individuos a qué otras, y se represen-
tan como un grafo dirigido. Conceptualmente, esta abstracción tiene ciertos paralelismos teóricos con las
interconexiones de nodos de un multicomputador representadas en la figura 2.5.
Existen muchos enfoques para construir la geometría de las interconexiones entre islas, pero los más
clásicos e interesantes ya han sido implementados en la biblioteca GAEDALib [9], y los mostramos en
la figura 3.13.
– 48 –
3.4. Algoritmos evolutivos paralelos
Rejilla Anillo Anillo doble
Grafo completo Grafo disconexo Conexión en pares
Figura 3.13: Topologías de islas implementadas en GAEDALib
3.4.2.2. Sincronización entre islas
La manera en que las islas se coordinan para migrar los individuos nos plantea dos alternativas.
Modelo síncrono: En este modelo las islas se configuran para que intercambien los individuos
cada cierto número de generaciones, de manera que cada isla ejecutará de forma secuencial el
algoritmo evolutivo y, llegados a cierta generación preseleccionada, pasará a la fase de migración.
En la fase de migración las islas han de sincronizarse y esperar a que se envíen y reciban los
individuos. Esto provoca retardos, ya que las islas más rápidas deberán esperar por las más lentas.
Modelo asíncrono: En el modelo asíncrono las fases de evolución y de migración están acopladas.
Los envíos se realizan de forma asíncrona y, periódicamente, se comprueba si hay inmigrantes. De
este modo, no se producen retrasos, ya que cada nodo ejecutará a la mayor velocidad posible sin
tener que esperar por los nodos más lentos.
En resumen la paralelización de algoritmos evolutivos nos aporta ventajas en dos frentes, por un lado
puede ayudarnos a mejorar las soluciones obtenidas al evitar óptimos locales, y por otra lado nos aporta
una mejora a la eficiencia. Esta mejora se articula en dos sentidos, en el caso de los modelos maestro-
esclavos son adecuados cuando el cálculo del fitness es pesado y en el caso de los modelos de islas nos
pueden aportar superlinealidad, dado el buen comportamiento de los algoritmos evolutivos a la hora de
ser paralelizados.
– 49 –
Parte III
Diseño y desarrollo de la solución
Capítulo 4
Multiple offspring sampling geneticalgorithm en GAEDALib
4.1. Introducción
En este proyecto fin de carrera se ha llevado a cabo la implementación de un algoritmo genético
basado en MOS que extiende la libreria de algoritmos evolutivos GAEDALib que, a su vez, suponía una
extensión de la librería de algoritmos genéticos Genetic Algorithm Library (GALib). Todas las versiones
de las librerías han sido implementadas en C/C++ siguiendo, en la medida de lo posible, una metodología
orientada a objetos.
MOS es un formalismo teórico que pretende ser capaz de explotar las posibles sinergías existentes
entre distintas técnicas de recombinación de individuos o, en el peor de los casos, ser capaz de detectar
cuál de estas técnicas es la mejor de las existentes sin que ello implique una merma en el rendimiento.
La idea fundamental de MOS consiste en combinar las diferentes aproximaciones evolutivas aprove-
chando los beneficios de cada una. MOS balancea dinámicamente la participación de cada mecanismo
evolutivo para generar la siguiente descendencia en función de la población anterior. Esta aproximación,
por tanto, evalúa diferentes mecanismos de generación de individuos ajustando los parámetros necesarios
para obtener las mejores poblaciones aprovechando las ventajas de cada mecanismo en cada momento.
MOS va más allá de la simple hibridación de técnicas de algoritmos genéticos, ya que ajusta dinámi-
camente la participación de cada una de estas técnicas o métodos de evolución en función de la calidad
que estima para cada método en cada momento del proceso evolutivo. La calidad es un concepto abs-
tracto que puede ser estimado en función de diferentes variables, por ejemplo el fitness o la edad de los
individuos.
– 53 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
Para evaluar el funcionamiento del enfoque MOS y la mejora que supone sobre un enfoque tradi-
cional se han llevado a cabo múltiples experimentos centrados fundamentalmente en la resolución de
problemas de permutaciones y, concretamente, en un problema clásico en la literatura como es el pro-
blema del viajante, o TSP por sus siglas en inglés, expondremos los resultados obtenidos en la sección
5.3. También se han realizado experimentos con funciones matemáticas clásicas para la evaluación de
algoritmos evolutivos, se comentarán en la sección 5.2.
Este capítulo pretende describir de forma exhaustiva el funcionamiento y la estructura del algoritmo
MOS. Inicialmente, profundizaremos en el diseño general del algoritmo en la sección 4.2, comentando
las dos alternativas que proponemos para evolucionar, la evolución central y la autonomic. A continua-
ción veremos con detalle, en las secciones 4.4 y 4.5, los dos elementos claves de la estructura MOS: las
técnicas y los genomas. Por último, en las secciones 4.6 y 4.7, comentaremos diferentes aspectos secun-
darios, aunque no por ello menos esenciales como la conversión entre representaciones y la serialización
de genomas MOS.
4.2. Diseño y arquitectura de MOS
En esta sección vamos a profundizar en el diseño del algoritmo y la estructura del mismo. Hemos
desarrollado 2 aproximaciones para afrontar la evolución, la aproximación MOS central que comentare-
mos en la sección 4.2.1 y la autonomic que desarrollaremos en la sección 4.2.2.
4.2.1. Aproximación MOS central
El algoritmo MOS, en la aproximación central, está basado en la estructura tradicional de un algo-
ritmo genético, que se refleja en el algoritmo 3.1, pero aplicando un enfoque de hibridación. Además, el
algoritmo MOS pretende integrar varios de los desarrollos teóricos realizados en torno a la hibridación
de algoritmos híbridos evolutivos, como los que referidos en [29], [16], [34], [4], [35] y [20]. El princi-
pal objetivo de MOS es ofrecer un entorno de trabajo homogéneo que dé soporte a la implementación
de diferentes combinaciones de algoritmos evolutivos, de una manera sencilla y con una ejecución con-
trolada. Por ejemplo, es de mucho interés adaptar y combinar dinámicamente las representaciones y los
operadores a nuestro problema en concreto, según las circunstancias.
La figura 4.1 muestra una visión general del funcionamiento del algoritmo MOS. En este esquema
podemos ver cómo aparece el nuevo concepto de técnica que nos presenta una nueva estructura dife-
renciada del modelo clásico de hibridación: un sólo algoritmo que está compuesto por varias técnicas
de recombinación. En la sección 4.4 profundizaremos en la estructura y funcionamiento de las técnicas
propuestas en MOS.
– 54 –
4.2. Diseño y arquitectura de MOS
Figura 4.1: Visión general del funcionamiento del algoritmo MOS central
El funcionamiento del algoritmo es sencillo y, en esencia, similar al concepto clásico de hibridación
de algoritmos evolutivos. Dada una población inicial, asignamos a cada técnica del conjunto de técnicas
disponibles una participación inicial. En función de esta participación, cada técnica generará una parte
proporcional de la población descendiente haciendo uso de los mecanismos propios de la técnica pa-
ra la recombinación de individuos. Por ejemplo, en una técnica EDA se usaría una red bayesiana con
determinada configuración y, en una técnica genética, unos operadores concretos de cruce y mutación.
Se evaluará la calidad de los hijos generados y esta calidad servirá por un lado para reajustar la
– 55 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
participación de las técnicas en la siguiente generación, y por otro para analizar qué hijos son los mejores
de los generados por las técnicas. Tras la creación de nuevos individuos, se evaluará la calidad de éstos
según una cierta medida. Esta calidad servirá para reajustar la participación de las técnicas en la siguiente
generación. Nuestro algoritmo, además, utiliza el concepto de elitismo, que fue comentado en el capítulo
3.2, para combinar la población actual y su descendencia y obtener la siguiente población.
La evaluación de la calidad se realizará en función del parámetro que más nos convenga según nuestro
problema. Estas medidas de calidad se pueden hacer en función del fitness medio de la población o de
otros factores como la edad de los elementos o la distancia dentro del espacio de búsqueda, según interese
más a nuestro problema.
La figura 4.2 muestra de una manera resumida el diagrama de secuencia de la generación de una
descendencia para el caso de la evolución central que acabamos de comentar. Las relaciones de las clases
que intervienen en la secuencia aparecen reflejadas en el diagrama de clases que aparece en la figura 4.4
que veremos más adelante. La descripción en profundidad de cada una de las clases y los métodos más
importantes la veremos a lo largo de las próximas secciones.
:GAMOSGA
step()
pop:GAPopulation
evaluate()
:GAMOSTechniqueSet
offspringAll(pop,auxPop)
:GAMOSTechnique
getPartRatio()
offspring (pop,auxPop,size,offset)
auxPop:GAPopulation
evaluate()
setTechQuality(techId)
setTechQuality()
add(auxPop)
remove(WORST)
Figura 4.2: Diagrama de secuencia del algoritmo MOS
El diagrama de secuencia de la figura 4.2 desarrolla el algoritmo comentado anteriormente. Podemos
observar que la generación de una descendencia implica en el algoritmo una llamada al método offspring
para todas las técnicas a través del wrapper que nos proporciona el conjunto de técnicas. Podemos ob-
servar como en el método offspring se especifica el tamaño de la parte de la población que debe generar
cada técnica, este cálculo se ha hecho en función de la participación. Vemos que después de que todas
– 56 –
4.2. Diseño y arquitectura de MOS
las técnicas hayan generado los nuevos descendientes se hace una evaluación de la población generada
para poder estimar la calidad de las técnicas, de cara a la siguiente iteración. Finalmente añadiremos los
individuos generados a nuestra población principal, aplicando en este caso elitismo.
4.2.2. Aproximación MOS autonomic
Como ya hemos visto a lo largo de este capítulo, hemos diseñado dos enfoques de evolución. El
primero, más tradicional, que hemos denominado central, ya ha sido expuesto en profundidad en las sec-
ciones anteriores. El otro método de evolución denominado autonomic es más novedoso en este sentido
y propone un nuevo enfoque. Está basado en el concepto de presión evolutiva, es decir, supone que el
mero hecho de aplicar elitismo y seleccionar los mejores individuos en cada iteración ya define intrínse-
camente en cierta manera qué técnicas son las mejores, siempre y cuando llevemos un registro de con qué
técnica fue generado un genoma. Este método evolutivo sólo es aplicable cuando manejamos técnicas
de tipo genético, es decir, que instancien objetos de la clase GAMOSTechniqueGA, ya que son las únicas
técnicas que pueden generar individuos en base a sólo 2 individuos, y esto es necesario como veremos
más adelante. A continuación comentaremos las líneas fundamentales de su funcionamiento.
Como ya hemos comentado en la sección 4.5, los genomas MOS incorporan, entre otras cosas, un
vector de probabilidades. Este vector de probabilidades es del mismo tamaño que el número de técnicas
que estemos utilizando en nuestro algoritmo, y tiene la finalidad de asociar una probabilidad a cada
técnica por cada genoma MOS, es decir, por cada individuo de la población. Por definición, la suma
de las probabilidades de cada vector debe ser igual a 1. Las probabilidades se inicializan de manera
equitativa entre todas las técnicas para cada individuo.
La figura 4.3 muestra el diagrama de secuencia del modelo autonomic, que difiere del modelo central.
La diferencia fundamental estriba en que no llevamos un cálculo de la participación de cada técnica. A
la hora de evolucionar para generar una nueva descendencia recorremos la población y no el conjunto de
técnicas. Para cada pareja de individuos recuperamos sus vectores de probabilidad y los combinamos (el
método más directo, y el que estamos utilizando, es mediante la media aritmética). Esto genera un nuevo
vector de probabilidades, que usaremos para escoger una técnica de entre todas las que disponemos. Por
tanto, una técnica con una probabilidad alta tendrá más posibilidades de ser seleccionada. La técnica
escogida es con la que recombinaremos los individuos para generar los nuevos hijos (en el caso general,
dos padres generarán dos hijos). Además, fijaremos los vectores de probabilidades de los hijos como el
vector obtenido al combinar los de los padres y que habíamos calculado anteriormente, pero con una
bonificación a la probabilidad de la técnica ganadora, que es con la hemos generado dichos hijos.
– 57 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
evaluate()
offspring (dad, mom, auxPop, size, offset, probVectorChild)
:GAMOSGA
step()
pop:GAPopulation
select()
:GAMOSTechniqueSet
getTechnique(techId)
:GAMOSTechnique
bonusTechnique(probVectorChild,techId)
add(auxPop)
remove(WORST)
auxPop:GAPopulation
Figura 4.3: Diagrama de secuencia del algoritmo MOS autonomic
Con este mecanismo los individuos que sobrevivan, que serán los mejores, tendrán un vector de
probabilidades donde habrá sido bonificada la probabilidad de la técnica que los generó. De esta manera,
en la siguiente generación estas técnicas que generan individuos buenos tendrán más posibilidades de
ser seleccionadas para evolucionar los nuevos individuos. Por lo tanto, la tendencia general será a que
las técnicas que generen mejores individuos generen más individuos y, de este modo, individuos aún
mejores, llegando antes a la convergencia.
4.2.3. Relación de MOS y GAEDALib
MOS ha sido introducido como un posible algoritmo más dentro de la estructura de algoritmos que
ofrece GAEDALib [9]. En la figura 4.4 se pueden ver de una forma resumida y simplificada las clases
que han sido añadidas en GAEDALib para dar soporte al algoritmo MOS. Las clases añadidas aparecen
en color azul, mientras que las clases ya existentes están en color negro.
– 58 –
4.3. Clase GAMOSGA
Figura 4.4: Clases de GAGeneticAlgorithm
En las siguientes secciones describiremos con detenimiento los aspectos más relevantes de cada una
de estas nuevas clases.
4.3. Clase GAMOSGA
A continuación detallamos con una breve descripción los métodos implementados más significativos
de la clase GAMOSGA y que tienen un papel relevante en el funcionamiento del algoritmo MOS comentado
en la sección 4.2.
– 59 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
void GAMOSGA::initialize(int seed)
Inicializa el algoritmo. Esto consiste en inicializar el generador de números aleatorios en función
de la semilla suministrada. Además, fija los ratios de participación iniciales, obtiene una referencia
al objeto conversor de codificaciones de genomas e inicializa la población inicial y las estadísticas.
void GAMOSGA::setEvolutiveApproach(evolutionType evolutiveApproach)
Define el tipo de evolución que se usará en el proceso evolutivo. Puede ser una evolución central,
como la comentada en la sección 4.2.1, o una evolución autonomic, como la comentada en la
sección 4.2.2.
void GAMOSGA::step()
Evoluciona una generación, produciendo una descendencia. Dependiendo del tipo de evolución
fijado llamará al método stepCentral() o a stepAutonomic().
GAMOSTechniqueSet& GAMOSGA::getTechSet()
Devuelve una referencia al conjunto de técnicas definidas para el algoritmo. En la sección 4.4.4 se
profundizará sobre la estructura y funcionalidad de un conjunto de técnicas modelizado en la clase
GAMOSTechniqueSet.
void GAMOSGA::setParticipationFunction(ParticipationFunction
partFunction)
Establece la función de participación que se utilizará para calcular la participación de las técnicas
en cada iteración del proceso evolutivo. El parámetro partFunction es un puntero a una función
externa.
void GAMOSGA::setMinParticipation(double minPart)
Con este método podemos fijar un valor mínimo de participación que será tenido en cuenta por
la función de participación, de manera que a ninguna técnica se le asigne un valor menor que
minPart.
GAMOSGA* GAMOSGA::stepCentral()
Genera una descendencia de la población utilizando el método central. Para generar los individuos
hace uso de todas las técnicas en función de su participación.
GAMOSGA* GAMOSGA::stepAutonomic()
– 60 –
4.4. Técnicas MOS
Genera una descendencia de la población utilizando el método autonomic. Para generar los indi-
viduos, hace uso de todas las técnicas en función de las probabilidades almacenadas tal y como se
vio en la sección 4.2.2.
void GAMOSGA::updatePartRatios()
Actualiza los ratios de participación de las técnicas. Para esto hace uso de la función de participa-
ción definida.
void GAMOSGA::evalTechQuality(GAPopulation* evalPop)
Evalúa la calidad del conjunto de técnicas definido en función de una población dada. Para ello,
tiene en cuenta los individuos generados por cada técnica.
GAMOSTechnique* GAMOSGA::selectTechnique(GAMOSProbVector&
probVector)
Dado un vector de probabilidades de técnicas, selecciona una técnica. Las técnicas cuya probabi-
lidad en el vector sea más alta tendrán mas posibilidades de ser seleccionadas. Se usa en el caso
de evolución autonomic, comentado en la sección 4.2.2.
void GAMOSGA::mixProbVector(GAMOSProbVector& pvDad, GAMOSProbVector
& pvMom, GAMOSProbVector& pvChild)
Dados dos vectores de probabilidades de dos individuos que actúan de padre y de madre se mezclan
(en principio haciendo la media, aunque se podría definir otro procedimiento) las probabilidades
para volcarlas en un tercer vector de probabilidades perteneciente al hijo. Se usa en el caso de
evolución autonomic, como se vio en la sección 4.2.2.
4.4. Técnicas MOS
Un nuevo concepto fundamental que ha sido introducido en la arquitectura MOS y que supone la
espina dorsal de la misma son las técnicas. Una técnica MOS es un concepto abstracto que agrupa una
serie de operadores y características propias y necesarias para evolucionar una población de individuos.
Toda técnica MOS se caracteriza por tener los siguientes elementos:
Toda técnica ha de tener un identificador único de manera que pueda ser localizada y referenciada
con facilidad. En este caso, se ha decidido implementar los identificadores de las técnicas como
números enteros. El identificador se asigna en el momento de la construcción de la técnica, lo
cual tiene lugar cuando estamos definiendo nuestro problema. Cada problema puede requerir usar
– 61 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
diferentes técnicas según sus características, ya que unas técnicas resolverán mejor unos problemas
que otros. Por eso, una técnica debe ser definida al nivel de definición del problema y debe ser
configurada de la manera adecuada para que resuelva nuestro problema lo mejor posible.
Por otro lado, toda técnica lleva asociada una calidad, que define lo buena que es esa técnica a
la hora de generar individuos nuevos. En nuestro implementación este cálculo se hace en base
al fitness de los individuos generados. La calidad es un concepto que ayuda a las funciones de
participación a reasignar en cada nueva iteración la futura participación de cada técnica. La calidad
de cada técnica se reevalúa en cada nueva generación del proceso evolutivo. La calidad es un valor
numérico.
La participación de una técnica es un porcentaje calculado por la función de participación en
función de la calidad. El algoritmo reparte los individuos de la población a generar en función de
las participaciones de cada técnica. Por supuesto, las participaciones de todas las técnicas deben
sumar el 100 %, ya que en una generación todo elemento de la población generada, o descendencia,
debe haber sido producido por una técnica. Las participaciones se recalculan en cada generación
después de haber calculado las calidades.
Cada técnica trabaja sobre un tipo de genoma. Un genoma está intimamente relacionado con una
codificación, de manera que una codificación es utilizada como identificador de un tipo de genoma.
Una técnica se relaciona con una codificación y almacena un genoma. Este genoma también es
construido en el momento de la definición del problema y es a partir de la estructura de este
genoma que generaremos todos los demás genomas que formarán nuestra población.
Por último, toda técnica debe tener al menos dos operadores. El operador de inicialización que,
dado un genoma que hayamos copiado del genoma base, es capaz de inicializarlo cumpliendo los
requisitos y necesidades de nuestro problema. Y el operador de evaluación que, dado un genoma,
sea capaz de evaluarlo y de calcular su valor de adecuación (score), el score es equivalente al
fitness, pero no está escalado. Por supuesto, cada tipo de genoma en cada problema debe tener un
operador de evaluación diferente, que sea capaz de calcular lo buena que es la solución modelizada
en un genoma dado para un problema concreto. En muchas ocasiones nos interesará comparar la
evaluación de nuestro genoma con un valor óptimo conocido y adecuado a nuestro problema, de
manera que podamos expresar el score de manera relativa, abstrayéndonos de qué problema o
conjunto de datos estemos utilizando.
– 62 –
4.4. Técnicas MOS
GAMOSTechniqueGA GAMOSTechniqueEDA
GAMOSTechnique
Figura 4.5: Tipos de técnicas MOS
Una técnica MOS en si misma no tiene ningún sentido, ya que no es capaz de generar nuevos in-
dividuos. Hay dos enfoques, como muestra la figura 4.5, que instancian el concepto de técnica MOS
y que han sido adaptadas del funcionamiento tradicional de GAEDALib. El primero es el enfoque tra-
dicional de los algoritmos genéticos, lo que da lugar a la clase GAMOSTechniqueGA; el segundo es el
enfoque de los algoritmos de estimación de la distribución de probabilidad, que utilizan redes bayesianas
o gaussianas para estimar probabilidades y calcular así los mejores individuos, lo cual da lugar a la clase
GAMOSTechniqueEDA. En esta implementación solo hemos desarrollado estos 2 tipos de técnicas, pero la
arquitectura MOS da cabida a nuevas implementaciones de técnicas basadas en otros modelos evolutivos
como evolución difererencial o particle swarn optimization. El único requisito es que el modelo evolutivo
se pueda adaptar a los interfaces definidos proporcionando los mecanismos necesarios para realizar su
propio offspring.
4.4.1. Clase GAMOSTechnique
La clase GAMOSTechnique es una clase abstracta que proporciona un interfaz homogéneo a todas
las clases derivadas que hereden de esta clase y que representen un técnica concreta según un enfo-
que evolutivo en particular. En este proyecto hemos implementado dos tipos de técnicas, las técnicas
GAMOSTechniqueGA que se basan en la teoría de algoritmos genéticos y que se detallan en la sección
4.4.2, y las técnicas GAMOSTechniqueEDA que se fundamentan en los estudios teóricos de los algoritmos
EDA, y que se comenta en la seccion 4.4.3.
A continuación se detallan los principales métodos que ofrece el interfaz abstracto de GAMOSTechnique.
void GAMOSTechnique::offspring(GAPopulation* origPop, GAPopulation*
destPop, unsigned size, unsigned offset)
Dada una población origen, la técnica deberá de usarla para generar una descendencia haciendo
uso de sus propias herramientas (por ejemplo, en una técnica genética, cruce y mutación). La
– 63 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
descendencia generada se almacenará en la población destino, pero debe ser del tamaño definido
en size y almacenarse dentro de la población con el desplazamiento que se indica en offset.
void GAMOSTechnique::offspring(GAMOSGenomeNew& dad, GAMOSGenomeNew&
mom, GAPopulation* destPop, unsigned size, unsigned offset,
GAMOSProbVector& probVectorChild)
Este método alternativo de generar descendencia es utilizado en el modelo de evolución autonomic
comentado en la sección 4.2.2. En este caso se generan los hijos en función de dos únicos indivi-
duos que actúan de padre y de madre. Los individuos generados se almacenarán, como en el caso
anterior, en la población destino con el tamaño y desplazamiento definidos. En este caso, además,
es necesario fijar en los hijos el vector de probabilidades correspondientemente actualizado.
double GAMOSTechnique::getQuality()
Devuelve la calidad de una técnica en un momento dado.
void GAMOSTechnique::setQuality(double quality)
Fija la calidad de una técnica.
void GAMOSTechnique::setPartRatio(double partRatio)
Fija el ratio de participación de una técnica.
encodingType GAMOSTechnique::getEncoding()
Devuelve la representación o codificación de los genomas con los que trabaja esta técnica.
GAGenome* GAMOSTechnique::getGenome()
Devuelve una nueva instancia de un genoma básico del tipo de genomas que usa esta técnica. No
está inicializado, pero puede servir de referencia para crear nuevos genomas a partir de uno dado.
void GAMOSTechnique::initGenome(GAGenome& gen)
Dado un genoma del tipo apropiado para la técnica, lo inicializa haciendo uso de la función de
inicialización inherente a la técnica.
double GAMOSTechnique::evalGenome(GAGenome& gen)
Dado un genoma que se ajuste a la técnica, calculamos la evaluación de su fitness utilizando la
función de evaluación propia para el tipo de genoma correspondiente y que está vinculada con la
técnica.
– 64 –
4.4. Técnicas MOS
4.4.2. Técnicas MOS GA
Una técnica MOS de tipo GA modeliza todo lo necesario para evolucionar una población desde el
enfoque tradicional de un algoritmo genético. Es decir, una técnica de este tipo tendrá los siguientes
elementos:
Operador de cruce: Este operador es capaz de, dados dos genomas, cruzarlos para obtener dos
hijos. Hay muchas formas y técnicas para cruzar dos genomas, y éstas dependen directamente de
cómo estén codificados los individuos. Por eso una técnica, además de operadores, también tiene
asociado un tipo de genoma que se corresponda con una codificación en concreto, como ya se
comentó en la sección 4.4.
Probabilidad de cruce: Representa la probabilidad de aplicar realmente el operador del punto
anterior. Este parámetro se puede ajustar en cada técnica según nos convenga.
Operador de mutación: Este operador es capaz de, dado un genoma, aplicarle ciertas modifi-
caciones o mutaciones que alteren su codificación. Como en el caso del operador de cruce, hay
muchos operadores de mutación y cada operador va asociado a una codificación concreta.
Probabilidad de mutación: Al igual que en el caso del cruce, no siempre es necesario mutar un
genoma y nos puede interesar hacerlo en función de una probabilidad. Esta probabilidad se puede
fijar de manera independiente para cada técnica.
4.4.3. Técnicas MOS EDA
Una técnica EDA está basada en el desarrollo teórico de los algoritmos evolutivos EDA comentado
en la sección 3.3. Una técnica EDA está intrínsecamente asociada a una red de aprendizaje, que diferirá
en función de la codificación de los genomas con los que trabaje. Por un lado tenemos las redes bayesia-
nas, asociadas a problemas discretos y, por otro, las redes gaussianas asociadas a problemas continuos.
Según el tipo de red que utilicemos será necesario definir un modelo de aprendizaje y unas técnicas de
simulación y de cálculo del fitness distintas.
4.4.4. Conjunto de técnicas
Por encima del concepto de técnicas hemos desarrollado la clase GAMOSTechniqueSet, que abstrae
un conjunto de técnicas y ofrece gran funcionalidad para operar sobre dicho conjunto. A continuación
reseñamos alguno de los métodos más interesesantes de esta clase.
– 65 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
bool GAMOSTechniqueSet::registerTechnique(GAMOSTechnique* tech)
Registramos la técnica pasada como argumento en el conjunto de técnicas.
GAMOSTechnique* GAMOSTechniqueSet::getTechnique(techIdType
techniqueId)
Dado un identificador de técnica, recuperamos la técnica correspondiente.
unsigned GAMOSTechniqueSet::nTechniques()
Obtenemos el número de técnicas disponibles en el conjunto.
void GAMOSTechniqueSet::offspringAll(GAPopulation* origPop,
GAPopulation* destPop)
Utilizado en la variante de evolución central, evoluciona para generar la siguiente población ha-
ciendo uso de todas las técnicas. Tiene en cuenta los ratios de participación establecidos.
void GAMOSTechniqueSet::initPartRatios();
Inicializa de forma equitativa los ratios de participación de todas las técnicas.
void GAMOSTechniqueSet::setTechQuality(techIdType techniqueId,
double quality)
Establece la calidad de una técnica.
techIdType GAMOSTechniqueSet::getBestTechniqueId()
Obtiene el identificador de la técnica que más calidad tiene en ese momento.
GAMOSProbVector& GAMOSTechniqueSet::bonusTechnique(GAMOSProbVector&
probVector, techIdType techniqueId)
Se usa en la variante autonomic. Bonifica la probabilidad de una técnica dada en el vector de
probabilidades suministrado, según los criterios establecidos. Consecuentemente, decrementa la
probabilidad del resto de técnicas.
4.5. Genomas MOS
Un aspecto fundamental de la arquitectura propuesta en el algoritmo MOS es el papel que desem-
peñan los genomas MOS. Tradicionalmente, un genoma codifica en una determinada representación la
– 66 –
4.5. Genomas MOS
información referente a un individuo, como ya comentamos en el capítulo 3. En MOS, la representa-
ción de un genoma está intrínsecamente relacionada a la técnica con la que queremos evolucionar dicho
genoma, como acabamos de ver en las secciones anteriores.
Una de las necesidades que surgen al plantear MOS es la posibilidad de ir utilizando las diferentes
técnicas que componen nuestro conjunto de técnicas. Alternativamente, según marquen la calidad y la
participación, iremos aplicando estas técnicas sobre los individuos de la población que vayan sobrevi-
viendo. Sin embargo, cada técnica tiene la necesidad de que el individuo contenga una representación
adecuada de su genoma, para poder aplicar sus operadores sobre el mismo.
La solución que proponemos a este problema es desarrollar el concepto de genoma MOS como
contenedor de diferentes genomas con diferentes representaciones. Todos los genomas contenidos hacen
referencia al mismo individuo y, en cierta forma, contienen la misma información, pero codificada de
manera diferente, según nos convenga en función de las técnicas que queramos usar.
La figura 4.6 muestra la estructura de clases que acabamos de comentar. Podemos ver que la clase
GAMOSGenome que implementa los genomas MOS hereda de la clase GAGenome, como todos los geno-
mas, pero a la vez es un contenedor de otros objetos de la clase GAGenome. Esto nos permite contener
varios genomas en un individuo pero seguir manteniendo el mismo interfaz de cara a las poblaciones de
individuos, que se modelizan como conjuntos de genomas.
Figura 4.6: Diagrama de clase de genomas MOS
– 67 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
Por otro lado, los genomas MOS añaden una funcionalidad adicional diseñada para la implementa-
ción del mecanismo de evolución autonomic. Consiste, en esencia, en que cada genoma MOS incorpora,
además de todo lo ya mencionado, un vector de probabilidades de tamaño igual al número de técnicas.
Este vector es utilizado en el modelo de evolución autonomic que se comentó en la sección 4.2.2.
4.5.1. Clase GAMOSGenome
Como hemos comentado anteriormente, la clase GAMOSGenome implementa los genomas MOS. Ade-
más, hereda de la clase GAGenome y es un contenedor de objetos de la clase GAGenome. A continuación
comentamos los principales métodos implementados en la clase GAMOSGenome, que suponen una novedad
respecto a los ya implementados en GAGenome.
void GAMOSGenome::updateProbVector(GAMOSProbVector& probVector)
Actualiza el vector de probabilidades con el nuevo vector suministrado. Se utiliza en el caso de
evolución autonomic.
void GAMOSGenome::updateTechProb(techIdType techId, double prob)
Actualiza la probabilidad de una técnica dada en el vector de probabilidades, según la probabilidad
suministrada. Como el método anterior, se utiliza sólo en el caso de evolución autonomic.
bool GAMOSGenome::existEncoding(encodingType encoding)
Comprueba si el genoma MOS contiene un genoma con la codificación suministrada.
void GAMOSGenome::addEncoding(encodingType encoding, GAGenome* gen)
Añade un nuevo genoma al contenedor de genomas del genoma MOS. El genoma queda registrado
e indexado en función de su codificación.
GAGenome* GAMOSGenome::getGenome(encodingType encoding)
Devuelve un puntero al genoma almacenado en el contenedor cuyo identificador de codificación
se corresponde con el suministrado.
GAMOSEncodingSet& GAMOSGenome::getEncodingSet()
Devuelve una referencia al contenedor de genomas de un genoma MOS.
void GAMOSGenome::purgeGenome(GAMOSTechnique* technique)
– 68 –
4.6. Conversor MOS
Elimina todas los genomas existentes en el contenedor del genoma MOS, salvo el que se corres-
ponda con la codificación utilizada en la técnica suministrada. En caso de no existir un genoma con
esta codificación, lo crea. Este método se utiliza en los hijos antes de realizar un cruce con técni-
cas de recombinación basadas en algoritmos genéticos, para limpiar el genoma MOS de genomas
obsoletos.
4.6. Conversor MOS
Uno de los aspectos necesarios con el nuevo modelo de genoma planteado en MOS es la conversión
entre diferentes codificaciones. Esto es debido a que cada técnica requiere que un individuo contenga
un genoma con la representación adecuada para poder generar su descendencia. Con el modelo MOS es
posible que un genoma de este tipo contenga varias representaciones equivalentes pero que ninguna sea la
que necesita la técnica con la que se va realizar la recombinación. Por esto, es necesario comprobar, antes
de aplicar ningún operador de una técnica sobre un genoma, que el genoma contiene la representación
adecuada. De no ser así será necesario convertir una de las codificaciones existentes a la codificación que
nos interesa y almacenar ese nuevo genoma en el contenedor de genomas del genoma MOS, como se
muestra en la figura 4.7.
Figura 4.7: Funcionamiento del conversor MOS
La funcionalidad del conversor se ha implementado en la clase GAMOSConversion. El diseño que
hemos escogido para el conversor de codificaciones consiste en una clase de tipo singleton como aparece
reflejado en el diagrama de la figura 4.4. Esto quiere decir que se trata de una clase que sólo puede
instanciarse una vez, y de la que se puede recuperar una referencia desde cualquier otro objeto de la
biblioteca.
– 69 –
4. Multiple offspring sampling genetic algorithm en GAEDALib
La lógica del conversor es muy sencilla. Por un lado, podemos registrar funciones de conversión, que
convierten genomas de una codificación a otra. Por otro lado, podemos solicitar al conversor que nos
convierta un genoma dado en una codificación a un genoma con otra codificación. Para realizar esto, el
conversor buscará la función de conversión adecuada entre las que tenga registradas y la llamará.
A continuación describimos brevemente los métodos que hemos implementada para llevar a cabo la
labor que acabamos de describir.
GAMOSConversion* GAMOSConversion::handle()
Obtiene una referencia al conversor. Al ser una clase de tipo singleton no lo podemos instanciar, y
ésta es la única manera de llamar a sus métodos.
bool GAMOSConversion::registerConvFunction(encodingType codOrig,
encodingType codDest, ConversionFunction convFunction)
Registra una función de conversión que convierte genomas de una codificación origen a una codi-
ficación destino.
bool GAMOSConversion::convertGenome(encodingType codOrig,
encodingType codDest, GAGenome* genOrig, GAGenome* genDest)
Convierte un genoma codificado de cierta manera a un genoma codificado de la manera que le
especifiquemos. Es necesario que, previamente, hayamos registrado la función de conversión ade-
cuada.
4.7. Serializador MOS
Para finalizar este capítulo, expondremos la necesidad de serializar los genomas MOS, y cómo se ha
implementado dicha funcionalidad. Como se comentó en la sección 3.4.2, un enfoque muy interesante,
y que proporciona muchas ventajas a la hora de paralelizar una algoritmo evolutivo como lo es MOS,
consiste en la implantación de un modelo de ejecución basado en islas autónomas con migración de los
mejores individuos. Para migrar individuos de una isla a otra, la implementación de GAEDALib hace
uso de la biblioteca de paso de mensajes MPI. Para poder enviar un genoma como un mensaje MPI es
necesario que éste esté serializado en un buffer en memoria.
Otros lenguajes de programación modernos dan soporte automático a la serialización y deserializa-
ción de objetos, pero GAEDALib está implementada en C++ y no soporta serialización automática, de
manera que es necesario implementarla aparte.
– 70 –
4.7. Serializador MOS
La arquitectura del serializador de genomas MOS que hemos implementado está basada en dos ni-
veles. Por un lado, tenemos un conjunto de serializadores de genomas que son capaces de serializar
cualquier genoma simple que tenga una codificación concreta. Por otro lado, tenemos el serializador de
los genomas MOS que, en primer lugar, serializa la información relativa al genoma MOS y, a continua-
ción, va a llamando a todos los serializadores de genomas que sean necesarios para serializar todas las
codificaciones que contenga el genoma MOS que estamos serializando. El proceso de deserialización en
la isla receptora es análogo. La figura 4.8 muestra la arquitectura que acabamos de comentar.
Figura 4.8: Funcionamiento del serializador MOS
Con esta arquitectura, al añadir una nueva codificación sólo tendríamos que implementar el serializa-
dor y el deserializador concreto de esa codificación y registrarlo en el serializador de MOS. No entramos
en detalle en los métodos y funcionamiento de la serialización ya que no es el objeto de este proyecto.
– 71 –
Parte IV
Análisis de resultados
Capítulo 5
Análisis de resultados
5.1. Introducción
En este capítulo vamos a realizar un análisis detallado de los resultados obtenidos en diversos experi-
mentos con el desarrollo realizado en la implementación del algoritmo MOS. El análisis de resultados se
va a dividir en dos grandes bloques, el primero analizando los resultados obtenidos al aplicar el algorit-
mo evolutivo a diversas funciones matemáticas clásicas y el segundo al aplicarlo al problema del viajante
(TSP), utilizado recurrentemente como ejemplo de problema a ser resuelto por algoritmos evolutivos, ya
que es un buen modelo genérico clásico. El problema del TSP se detallará en la sección 5.3.1.
Para realizar los experimentos hemos definido un conjunto de técnicas genéticas. Estas técnicas se
basan en los conceptos y operadores desarrollados en el capítulo 3 siguiendo la estructura comentada en
la sección 4.4. Además de los operadores de cruce y mutación ya comentados, para la definición de una
técnica es necesario especificar un comparador (medida de distancia) y un inicializador.
Como comparador hemos utilizado el Simple Comparator (SC). Se trata de un comparador muy
sencillo que compara uno a uno los elementos de los vectores para ver si coinciden o no.
Para definir la inicialización hemos utilizado dos operadores: en el caso de técnicas de codificación
entera, el Permutation Initializer (PI), capaz de trabajar correctamente con permutaciones. Consiste en
inicializar el genoma con los valores enteros aceptados según el problema y mezclarlos aleatoriamente.
Para el caso de técnicas con codificación real, hemos utilizado el Uniform Initializer (UI), que inicia el
vector de reales de manera uniforme con números reales dentro del rango establecido.
– 75 –
5. Análisis de resultados
Codificación Inicializador Comparador Cruzador Mutador
IntPermOXREM Vector enteros PI SC OX REM
IntPermCXSIM Vector enteros PI SC CX SIM
IntPermOXSIM Vector enteros PI SC OX SIM
IntPermCXREM Vector enteros PI SC CX REM
RealOPCUM Vector reales UI SC OPC UM
RealUCUM Vector reales UI SC UC UM
RealBCUM Vector reales UI SC BC UM
RealUCGM Vector reales UI SC UC GM
RealBCGM Vector reales UI SC BC GM
IntUniOPXSM Vector enteros UI SC OPC SM
IntUniTPXSM Vector enteros UI SC TPC SM
IntUniEOXSM Vector enteros UI SC EOC SM
IntUniUXSM Vector enteros UI SC UC SM
Tabla 5.1: Técnicas GA definidas
Las técnicas basadas en codificaciones reales son aplicables en problemas de optimización de fun-
ciones matemáticas y también en problemas de permutaciones, aplicando los métodos adecuados de
codificación e interpretación. Por otro lado, las técnicas codificadas como vectores de enteros, se orien-
tan a resolver problemas de permutaciones, ya que respetan las restricciones impuestas por este tipo de
problemas, como el del TSP que comentaremos en la sección 5.3.
También se han definido dos tipos de técnicas EDA, basadas tanto en codificaciones discretas co-
mo continuas. La configuración de cada una de estas técnicas se muestra en la tabla 5.2. Además de
los parametros comentados en el capítulo 3, hemos utilizado como método de simulación el mecanis-
mo Partial Least Squares Correct (PLSC) y para el cálculo del score el método Bayesian Information
Criterion (BIC).
– 76 –
5.1. Introducción
Codificación Inic. Red Aprendizaje Sim. Res.
IntBayesUMDABICPLSC Vector enteros PI Bayesiana UMDA PLSC BIC
RealGaussUMDABIC Vector reales UI Gaussiana UMDA BIC
Tabla 5.2: Técnicas EDA definidas
Con el fin de simplificar la notación, vamos a redefinir el nombre con el que identificamos a las
técnicas. La tabla 5.3 recoge la equivalencia entre los nombres de de técnicas que veníamos utilizando
hasta ahora (definidos en la tabla 5.1) y los identificadores abreviados que utilizaremos a lo largo de este
capítulo.
Id. extendido Id. abreviado
IntPermOXREM t0
IntPermCXSIM t1
RealOPCUM t2
IntPermOXSIM t3
IntPermCXREM t4
IntBayesUMDABICPLSC t5
RealGaussUMDABIC t6
RealUCUM t7
RealBCUM t8
RealUCGM t9
RealBCGM t10
IntUniOPXSM t11
IntUniTPXSM t12
IntUniEOXSM t13
IntUniUXSM t14
Tabla 5.3: Equivalencia entre identificadores de técnicas
– 77 –
5. Análisis de resultados
5.2. Resultados con funciones matemáticas
En esta sección vamos a realizar una serie de experimentos con funciones matemáticas de optimi-
zación clásicas en el mundo de la computación evolutiva. Aplicaremos el algoritmo evolutivo MOS que
hemos desarrollado para intentar encontrar la mejor solución posible de la manera más rápida.
Estas funciones matemáticas, que detallaremos más adelante, trabajan sobre dominios continuos,
salvo el problema del Royal Road, que opera en un dominio discreto. Para resolver estos problemas
utilizaremos las técnicas diseñadas que utilizan números reales en el caso de los problemas de dominio
continuo, y números enteros en el caso del problema del Royal Road. Dichas técnicas fueron comentadas
en la sección 5.1.
El problema del maxbit lo resolveremos en la sección 5.2.1. Seguidamente, el problema del Royal
Road, definido por Holland [15], lo expondremos en la sección 5.2.2. A continuación, la función Grie-
wank, definida por Andreas Griewank [13], será expuesta en la sección 5.2.3. Por último, la función
Rastrigin será presentada en la sección 5.2.4.
Para estos cuatro problemas matemáticos analizaremos los resultados del fitness, los tiempos de
ejecución y el número de evaluaciones con distintos tamaños para cada problema. A la hora de calcular
el fitness hemos hecho una modificación en las funciones de evaluación, invirtiendo el resultado en los
problemas de minimización y escalándolo de manera que el óptimo se evalúe con un fitness igual a 1 y a
medida que la evaluación de un individuo empeore, este valor se aproxima a 0. Escalando el fitness así
es más facil comparar los resultados con los obtenidos con otros problemas.
5.2.1. Problema MaxBit
El problema MaxBit continuo se define como un problema de maximización de la siguiente función:
fMB(x) = ∑ni=1 xin
n(5.1)
Con 0≤ xi≤ 1. Esta función tiene el máximo absoluto en xi = 1 con f (x) = n. La figura 5.2.1 muestra
la superficie que genera la función con n = 2.
– 78 –
5.2. Resultados con funciones matemáticas
0
0.5
1
1.5
2
0 0.2
0.4 0.6
0.8 1
0
0.2
0.4
0.6
0.8
1
0
0.5
1
1.5
2
Figura 5.1: Superficie de la función MaxBit con n = 2
5.2.1.1. Resultados con MOS
Hemos aplicado MOS para intentar resolver el problema de maximización MaxBit. Los resultados
obtenidos con las diferentes combinaciones de técnicas genéticas y EDA que hemos utilizado se muestran
en la tabla 5.4. Para este experimento se ha usado un espacio de dimensión n = 12. En la tabla 5.5 se ve
el resultado con n = 30 y en la tabla 5.6 con n = 100. En todos los casos hemos utilizado una población
de 250 individuos.
– 79 –
5. Análisis de resultados
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 0.9999 0.396 48000
t6t8t9 0.9997 0.41 51000
t7t9t10 0.9992 0.202 62000
t8t9t10 0.9988 0.231 68000
t6t7t8t9t10 0.9998 0.427 54000
t7t8 0.9991 0.217 65000
t7t8t10 0.9989 0.237 69000
t7t8t9t10 0.9991 0.216 65000
t6t8t9t10 0.9998 0.417 52000
t6t8 0.9997 0.397 48000
t7t9 0.9932 0.148 54000
t10 0.9982 0.269 78000
t6t9t10 0.9999 0.403 50000
t6t7 0.9999 0.383 48000
t6t7t8 0.9999 0.405 50000
t9 0.9926 0.137 53000
t8t10 0.9981 0.272 77000
t6t7t8t9 0.9995 0.416 52000
t6t8t10 0.9998 0.418 51000
t7t8t9 0.9992 0.197 61000
t7t10 0.9991 0.218 65000
t6 0.9999 0.36 44000
t8 0.9981 0.268 78000
t6t7t9t10 0.9998 0.412 52000
t6t7t8t10 0.9997 0.425 53000
t8t9 0.9991 0.214 65000
t6t7t10 0.9998 0.403 50000
t6t7t9 0.9998 0.394 50000
t9t10 0.9991 0.215 66000
t6t9 0.9999 0.384 48000
t7 0.9925 0.144 54000
Tabla 5.4: Resultados para MaxBit con hibridación MOS central y n = 12
– 80 –
5.2. Resultados con funciones matemáticas
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 0.9976 2.1 67000
t6t8t9 0.9971 2.178 71000
t7t9t10 0.9961 0.369 92000
t8t9t10 0.9949 0.467 108000
t6t7t8t9t10 0.9971 2.321 76000
t7t8 0.9957 0.427 100000
t7t8t10 0.9949 0.475 108000
t7t8t9t10 0.9956 0.411 98000
t6t8t9t10 0.9973 2.274 74000
t6t8 0.9972 2.101 67000
t7t9 0.9885 0.268 74000
t10 0.9917 0.596 128000
t6t9t10 0.9976 2.202 71000
t6t7 0.9969 2.063 67000
t6t7t8 0.9972 2.183 71000
t9 0.9891 0.259 75000
t8t10 0.9918 0.605 127000
t6t7t8t9 0.9971 2.249 73000
t6t8t10 0.9973 2.256 72000
t7t8t9 0.9959 0.372 90000
t7t10 0.9957 0.412 98000
t6 0.9985 1.901 59000
t8 0.9919 0.605 125000
t6t7t9t10 0.9967 2.265 74000
t6t7t8t10 0.9972 2.258 73000
t8t9 0.9958 0.413 100000
t6t7t10 0.9971 2.196 71000
t6t7t9 0.9975 2.16 71000
t9t10 0.9955 0.396 99000
t6t9 0.9971 2.09 67000
t7 0.9876 0.285 77000
Tabla 5.5: Resultados para MaxBit con hibridación MOS central y n = 30
– 81 –
5. Análisis de resultados
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 0.9747 35.018 122000
t6t8t9 0.9745 37.218 130000
t7t9t10 0.9722 0.918 142000
t8t9t10 0.9678 1.207 171000
t6t7t8t9t10 0.9782 39.601 140000
t7t8 0.9768 1.243 165000
t7t8t10 0.9755 1.411 182000
t7t8t9t10 0.9723 1.103 159000
t6t8t9t10 0.9776 39.529 139000
t6t8 0.9688 32.288 112000
t7t9 0.9696 0.662 116000
t10 0.9301 1.771 202000
t6t9t10 0.9778 37.954 133000
t6t7 0.9672 32.604 114000
t6t7t8 0.9693 35.686 125000
t9 0.9683 0.569 112000
t8t10 0.9413 2.013 215000
t6t7t8t9 0.9761 37.513 132000
t6t8t10 0.975 37.907 133000
t7t8t9 0.9734 0.955 143000
t7t10 0.976 1.16 162000
t6 0.9668 26.178 90000
t8 0.9527 2.247 228000
t6t7t9t10 0.9772 38.237 135000
t6t7t8t10 0.9758 39.072 137000
t8t9 0.9686 1.022 153000
t6t7t10 0.9761 37.473 131000
t6t7t9 0.9755 37.191 131000
t9t10 0.9693 0.981 155000
t6t9 0.9744 32.935 115000
t7 0.9713 0.721 114000
Tabla 5.6: Resultados para MaxBit con hibridación MOS central y n = 100
– 82 –
5.2. Resultados con funciones matemáticas
En la tabla 5.4 vemos los resultados para el problema del MaxBit continuo con n = 12. Podemos
observar que con todas las combinaciones de técnicas se obtienen resultados muy buenos en el cálculo del
fitness, siempre mayores de 0.99. Esto es debido a que el tamaño del problema es pequeño y su resolución
resulta sencilla para el algoritmo MOS. Haciendo un análisis más exhaustivo, podemos darnos cuenta de
que los resultados con técnicas individuales son, en general, ligeramente inferiores a los resultados con
combinaciones de técnicas. Aunque la diferencia es mínima, vemos que vamos bien encaminados en
mejorar los resultados utilizando hibridación MOS. Sobre los tiempos observamos que la desviación que
existe es mínima. Si acaso, se incrementan ligeramente los tiempos con combinaciones de más técnicas,
probablemente debido a las sobrecargas introducidas en la lógica del algoritmo. Sobre el número de
evaluaciones, vemos que varía bastante en las técnicas individuales, y esto tiene una repercusión directa
en el número de evaluaciones de las combinaciones.
Para poder afinar más en las observaciones es necesario aumentar la complejidad del problema. Para
ello, en la tabla 5.5 hemos aumentado la dimensión del problema hasta un valor de n = 30 y en la tabla
5.6 hasta un valor de n = 100. Esto provoca que disminuya ligeramente el fitness y aumenten los tiempos.
Sin embargo, las conclusiones son similares al experimento con n = 12: el fitness, en general, mejora con
las combinaciones de técnicas frente a técnicas individuales, aunque la diferencia sigue siendo mínima
debido a la sencillez del problema, incluso aumentando la dimensión del mismo.
5.2.2. Problema Royal Road
El problema del Royal Road está compuesto por un conjunto de funciones. Fueron redefinidas por
Holland como un tipo de funciones adecuadas para ser optimizadas por un algoritmo genético.
Una función de esta familia toma como argumento una cadena de bits y devuelve un número real.
Cada cadena de bits está compuesta de 2k regiones de longitu b + g. Cada región está compuesta de
dos partes: el bloque de longitud b) y el hueco de longitud g. La parte del hueco es siempre ignorada,
utilizándose únicamente la parte del bloque para el cálculo del valor de la función.
La configuración propuesta por Holland consiste en: k = 4,b = 8,g = 7. Esto da como resultado ca-
denas de 240 bits, con 16 regiones cada una, bloques de 8 bits y huecos de 7 bits. Esta es la configuración
que usaremos en los experimentos.
5.2.2.1. Resultados con MOS
Hemos aplicado MOS para intentar resolver el problema de Royal Road. Los resultados obtenidos
con las diferentes combinaciones de técnicas genéticas y EDA que hemos utilizado se muestran en la
tabla 5.7. Hemos utilizado una población de 500 individuos.
– 83 –
5. Análisis de resultados
Técnicas Fitness Tiempo (seg.) Evaluaciones
t5t11t12t13 0.8694 4.628 88000
t13t14 0.5994 0.798 81000
t12t13 0.8774 0.65 84000
t5t14 0.635 8.473 107000
t5t13t14 0.6309 6.821 98000
t5t11t14 0.8743 5.763 101000
t11t12t13t14 0.8912 0.663 82000
t11t12t14 0.8573 0.593 74000
t5t12t14 0.9181 5.952 103000
t5t11t13t14 0.8452 5.09 95000
t5t11 0.8731 6.72 99000
t5t12 0.915 6.134 90000
t12 0.8427 0.504 71000
t11 0.8264 0.479 68000
t11t14 0.8784 0.733 92000
t14 0.6182 0.955 91000
t5t13 0.6089 6.82 81000
t5t11t13 0.8725 5.481 96000
t5t11t12t14 0.8891 4.997 93000
t12t14 0.9199 0.688 84000
t11t13t14 0.8818 0.732 90000
t11t12 0.861 0.488 68000
t11t12t13 0.8436 0.61 81000
t11t13 0.8365 0.62 81000
t13 0.5806 0.565 65000
t5t11t12t13t14 0.8892 5.01 98000
t5t12t13t14 0.9256 5.455 102000
t12t13t14 0.8978 0.763 92000
t5 0.6062 12.217 75000
t5t12t13 0.9246 5.599 99000
t5t11t12 0.9008 4.707 83000
Tabla 5.7: Resultados para Royal Road con hibridación MOS central, k = 4, b = 8 y g = 7
– 84 –
5.2. Resultados con funciones matemáticas
Los resultados obtenidos en el problema del Royal Road son mucho más interesantes que los obte-
nidos con el problema anterior. Se trata de un problema más complejo y diseñado específicamente para
ser resuelto por algoritmos evolutivos. Además, se trata de un problema discreto. Como se aprecia cla-
ramente en la tabla 5.7, los resultados del fitness para técnicas evolutivas individuales son relativamente
mediocres. Para facilitar esta observación, hemos recogido estos datos en la tabla resumen 5.8. El mejor
fitness obtenido es 0.8427 para la técnica t12, mientras que el resto de técnicas son todavía peores.
Técnicas Fitness
t12 0.8427
t11 0.8264
t14 0.6182
t5 0.6062
t13 0.5806
Tabla 5.8: Resumen de fitness para el problema Royal Road con técnicas individuales
Sin embargo, al aplicar hibridación MOS de estas mismas técnicas vemos cómo los resultados me-
joran de manera notable. En la tabla 5.9 recogemos de forma resumida los fitness de las 5 mejores
combinaciones MOS.
Técnicas Fitness
t5t12t13t14 0.9256
t5t12t13 0.9246
t12t14 0.9199
t5t12t14 0.9181
t5t12 0.915
Tabla 5.9: Resumen de mejores fitness para el problema Royal Road con hibridación MOS
Observamos cómo los resultados son realmente buenos al mejorar significativamente los fitness obte-
nidos individualmente. En este problema estamos sacando gran partido de la arquitectura MOS obtenien-
do muy buenos resultados al aprovechar y combinar las virtudes de cada técnica. Es interesante observar
que en las 5 mejores combinaciones aparece siempre la técnica t12 que, si bien es la mejor técnica indivi-
dual, lo es seguida muy de cerca por la técnica t11 que, sin embargo, no aparece en ninguna de estas cinco
combinaciones. Es también reseñable el incremento de fitness obtenido por la combinación de técnicas
t5t12, donde una técnica muy mala como t5 es capaz de incrementar significativamente el rendimiento de
la técnica t12.
– 85 –
5. Análisis de resultados
5.2.3. Función Griewank
La función Griewank define un problema de minimización sobre un espacio multidimensional:
fGri(x) =n
∑i=1
x2i
d−
n
∏i=1
cos(xi√
i)+1 (5.2)
Con −600≤ xi ≤ 600. Esta función tiene el mínimo absoluto en xi = 0 con f (x) = 0. El parámetro d
controla la profundidad de los mínimos locales: cuanto más grande sea este valor, más se parecerán los
mínimos locales al mínimo global. La figura 5.2.3 muestra la superficie que genera la función con n = 2.
0
0.5
1
1.5
2
2.5
-20-15-10-5 0 5 10 15 20
-20-15
-10-5
0 5
10 15
20
0
0.5
1
1.5
2
2.5
Figura 5.2: Superficie de la función Griewank con n = 2 y d = 4000
5.2.3.1. Resultados con MOS
Hemos aplicado MOS para intentar resolver el problema de minimización de la función Griewank.
Los resultados obtenidos con las diferentes combinaciones de técnicas genéticas y EDA que hemos
utilizado se muestran en las tablas 5.10, 5.11 y 5.12, con diferentes dimensiones del problema. En todos
los casos hemos utilizado una población de 250 individuos.
– 86 –
5.2. Resultados con funciones matemáticas
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 0.997 4.803 102000
t6t8t9 1.0 4.769 102000
t7t9t10 1.0 3.779 113000
t8t9t10 1.0 3.852 116000
t6t7t8t9t10 1.0 4.686 101000
t7t8 1.0 3.896 117000
t7t8t10 0.998 3.905 117000
t7t8t9t10 1.0 3.829 114000
t6t8t9t10 1.0 4.489 96000
t6t8 0.984 4.697 100000
t7t9 0.811 2.723 151000
t10 1.0 3.656 109000
t6t9t10 1.0 4.592 98000
t6t7 1.0 4.987 105000
t6t7t8 1.0 4.623 99000
t9 0.82 2.542 134000
t8t10 1.0 3.688 110000
t6t7t8t9 1.0 4.567 98000
t6t8t10 1.0 4.397 94000
t7t8t9 0.999 3.751 112000
t7t10 0.999 3.789 114000
t6 0.88 4.165 100000
t8 1.0 3.638 108000
t6t7t9t10 1.0 4.598 99000
t6t7t8t10 1.0 4.608 99000
t8t9 0.999 3.785 114000
t6t7t10 1.0 4.792 103000
t6t7t9 1.0 4.421 94000
t9t10 1.0 3.825 116000
t6t9 0.999 4.935 104000
t7 0.76 2.535 132000
Tabla 5.10: Resultados para Griewank con hibridación MOS central, n = 10 y d = 4000
– 87 –
5. Análisis de resultados
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 1.0 5.389 60000
t6t8t9 1.0 5.613 64000
t7t9t10 1.0 5.17 138000
t8t9t10 1.0 5.355 140000
t6t7t8t9t10 1.0 6.061 70000
t7t8 1.0 5.245 137000
t7t8t10 1.0 5.342 139000
t7t8t9t10 1.0 5.258 138000
t6t8t9t10 1.0 5.887 67000
t6t8 1.0 5.38 59000
t7t9 0.637 4.484 192000
t10 1.0 5.578 145000
t6t9t10 1.0 5.594 63000
t6t7 1.0 5.302 59000
t6t7t8 1.0 5.632 64000
t9 0.667 4.372 195000
t8t10 1.0 5.601 143000
t6t7t8t9 1.0 5.838 67000
t6t8t10 1.0 5.663 64000
t7t8t9 1.0 5.186 137000
t7t10 1.0 5.246 138000
t6 1.0 4.547 54000
t8 1.0 5.584 143000
t6t7t9t10 1.0 5.832 67000
t6t7t8t10 1.0 5.923 67000
t8t9 1.0 5.238 138000
t6t7t10 1.0 5.624 64000
t6t7t9 1.0 5.545 63000
t9t10 1.0 5.209 139000
t6t9 1.0 5.299 59000
t7 0.668 4.762 206000
Tabla 5.11: Resultados para Griewank con hibridación MOS central, n = 20 y d = 4000
– 88 –
5.2. Resultados con funciones matemáticas
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 1.0 10.065 66000
t6t8t9 1.0 10.545 71000
t7t9t10 0.9995 11.548 178000
t8t9t10 0.9994 9.965 185000
t6t7t8t9t10 1.0 11.267 77000
t7t8 0.9995 7.46 178000
t7t8t10 0.9995 11.809 182000
t7t8t9t10 0.9995 7.463 180000
t6t8t9t10 1.0 10.96 74000
t6t8 1.0 10.116 66000
t7t9 0.6449 6.926 250000
t10 0.9992 8.396 197000
t6t9t10 1.0 10.486 70000
t6t7 1.0 9.976 66000
t6t7t8 1.0 10.575 71000
t9 0.5972 6.224 212000
t8t10 0.9993 8.397 195000
t6t7t8t9 1.0 10.91 74000
t6t8t10 1.0 10.608 71000
t7t8t9 0.9995 11.926 176000
t7t10 0.9995 7.366 179000
t6 1.0 8.86 60000
t8 0.9993 8.4 193000
t6t7t9t10 1.0 10.939 74000
t6t7t8t10 1.0 11.007 74000
t8t9 0.9995 7.434 181000
t6t7t10 1.0 13.796 71000
t6t7t9 1.0 10.443 71000
t9t10 0.9994 7.455 183000
t6t9 1.0 9.959 66000
t7 0.6423 7.226 267000
Tabla 5.12: Resultados para Griewank con hibridación MOS central, n = 30 y d = 4000
– 89 –
5. Análisis de resultados
Observando las 3 tablas de datos obtenidas para el problema de optimización de la función Griewank,
lo primero que nos llama la atención es el mal comportamiento de las técnicas t7 y t9, tal y como se ve
en la tabla 5.13. Si consultamos la tabla 5.3 de traducción de identificadores, vemos que se trata de las
técnicas RealUCUM y RealUCGM, que tienen en común el operador de cruce uniforme. Por lo tanto,
de entrada podemos deducir que el operador de cruce Uniform Crossover no se comporta bien en el
problema Griewank.
Técnicas Fitness n = 10 Fitness n = 20 Fitness n = 30
t7 0.76 0.668 0.642
t9 0.82 0.667 0.597
t7t9 0.811 0.637 0.645
Tabla 5.13: Resumen de fitness de las peores técnicas para la función Griewank
En contraposición a estas 2 técnicas, que no son buenas para este problema, el resto de técnicas
configuradas son excelentes, ya sea de manera individual o hibridada. En todos los casos se optienen
resultados con un fitness por encima de 0.999 y, en muchas ocasiones, alcanzamos el óptimo. Este com-
portamiento se repite en los 3 experimentos realizados con n = 10, n = 20, n = 30.
Por lo tanto, y dejando al margen las 2 técnicas cuyo comportamiento es significativamente peor al
del resto y la hibridación entre ambas, podemos concluir que el problema de optimización de la fun-
ción Griewank es un problema que puede ser resuelto de forma adecuada con técnicas evolutivas. Sin
embargo, no es un buen problema para observar las bondades del algoritmo MOS, ya que las técnicas
individuales obtienen resultados muy buenos por sí solas, que apenas pueden ser mejorados al hibridarlas.
Sin embargo, sí que puede resultar interesante ver cómo en las hibridaciones donde participa uno de
las 2 técnicas malas, t7 y t9, el algoritmo MOS es capaz de sobreponerse a éstas y, a través, de sus me-
canismos de calidad y participación, sacar mejor partido de las otras técnicas para, finalmente, conseguir
un buen resultado minimizando la sobrecarga computacional introducida por técnicas mediocres. Esto
demuestra que la hibridación MOS es capaz de detectar qué técnicas tienen un comportamiento mejor
que otras y bonificarlas de tal manera que, si una de las técnicas hibridadas es incapaz de aportar nada al
proceso de búsqueda, sea descartada introduciendo el menor ruido posible.
Para terminar, podemos comentar sobre los tiempos de ejecución que, en general, están bastante
equilibrados entre diferentes combinaciones de técnicas y que crecen moderada y paralelamente al in-
cremento de la dimensión del problema.
– 90 –
5.2. Resultados con funciones matemáticas
5.2.4. Función Rastrigin
La función Rastrigin define un problema de minimización en un espacio multidimensional. La fun-
ción de evaluación es la siguiente:
fRas(x) = a ·n+n
∑i=1
(x2i −a · cos(ω · xi)) (5.3)
Con −5,12 ≤ xi ≤ 5,12. Esta función tiene el mínimo absoluto en xi = 0 con f (x) = 0. La figura
5.2.4 muestra la superficie que genera la función con n = 2.
0 10 20 30 40 50 60 70 80 90
-4-2
0 2
4
-4
-2
0
2
4
0 10 20 30 40 50 60 70 80 90
Figura 5.3: Superficie de la función Rastrigin con n = 2, ω = 2π y a = 10
5.2.4.1. Resultados con MOS
Hemos aplicado MOS para intentar resolver el problema de minimización de la función Rastrigin.
Los resultados obtenidos con las diferentes combinaciones de técnicas genéticas y EDA que hemos
utilizado se muestran en las tablas 5.14, 5.15 y 5.16, con diferentes dimensiones para el problema. En
todos los casos, hemos utilizado una población de 1000 individuos.
– 91 –
5. Análisis de resultados
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 1.0 2.675 79000
t6t8t9 1.0 2.134 60000
t7t9t10 1.0 1.88 59000
t8t9t10 1.0 2.091 65000
t6t7t8t9t10 1.0 2.096 58000
t7t8 1.0 1.953 61000
t7t8t10 1.0 2.077 65000
t7t8t9t10 1.0 1.933 60000
t6t8t9t10 1.0 2.253 63000
t6t8 1.0 2.71 80000
t7t9 0.961 1.161 69000
t10 1.0 2.449 80000
t6t9t10 1.0 2.138 60000
t6t7 1.0 1.91 55000
t6t7t8 1.0 2.135 60000
t9 0.968 1.156 70000
t8t10 1.0 2.407 78000
t6t7t8t9 1.0 2.008 56000
t6t8t10 1.0 2.642 77000
t7t8t9 1.0 1.869 58000
t7t10 1.0 1.965 61000
t6 0.335 1.889 65000
t8 1.0 2.418 79000
t6t7t9t10 1.0 2.016 56000
t6t7t8t10 1.0 2.245 62000
t8t9 1.0 1.943 61000
t6t7t10 1.0 2.132 60000
t6t7t9 1.0 1.854 52000
t9t10 1.0 1.93 60000
t6t9 1.0 1.902 55000
t7 0.948 1.162 70000
Tabla 5.14: Resultados para Rastrigin con hibridación MOS central, n = 5, a = 10 y ω = 2π
– 92 –
5.2. Resultados con funciones matemáticas
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 0.387 18.772 227000
t6t8t9 0.991 10.31 121000
t7t9t10 0.991 5.088 136000
t8t9t10 0.996 5.648 151000
t6t7t8t9t10 0.996 10.096 120000
t7t8 0.998 5.366 140000
t7t8t10 0.998 5.617 149000
t7t8t9t10 1.0 5.325 141000
t6t8t9t10 0.997 11.051 131000
t6t8 0.339 18.591 225000
t7t9 0.918 4.55 215000
t10 0.925 14.822 407000
t6t9t10 0.994 10.194 120000
t6t7 0.993 9.292 107000
t6t7t8 0.993 10.429 122000
t9 0.928 4.401 213000
t8t10 0.999 15.711 420000
t6t7t8t9 0.992 9.725 115000
t6t8t10 0.733 29.591 358000
t7t8t9 0.994 5.267 140000
t7t10 0.999 5.328 140000
t6 0.011 5.822 69000
t8 0.975 16.508 443000
t6t7t9t10 0.997 9.546 113000
t6t7t8t10 1.0 10.936 130000
t8t9 0.997 5.584 148000
t6t7t10 0.995 10.086 119000
t6t7t9 0.994 8.817 103000
t9t10 0.998 5.353 143000
t6t9 0.993 9.397 109000
t7 0.903 4.526 216000
Tabla 5.15: Resultados para Rastrigin con hibridación MOS central, n = 20, a = 10 y ω = 2π
– 93 –
5. Análisis de resultados
Técnicas Fitness Tiempo (seg.) Evaluaciones
t6t10 0.3001 52.965 371000
t6t8t9 0.9695 22.771 158000
t7t9t10 0.9897 8.244 204000
t8t9t10 0.9917 8.322 205000
t6t7t8t9t10 0.9593 22.378 157000
t7t8 0.9908 8.111 197000
t7t8t10 0.9961 8.414 204000
t7t8t9t10 0.9916 8.131 198000
t6t8t9t10 0.981 24.692 173000
t6t8 0.2377 43.141 303000
t7t9 0.8666 7.094 292000
t10 0.4837 20.624 520000
t6t9t10 0.9811 22.456 157000
t6t7 0.962 20.578 141000
t6t7t8 0.9713 22.789 158000
t9 0.9154 7.059 292000
t8t10 0.6931 24.551 604000
t6t7t8t9 0.9644 21.63 151000
t6t8t10 0.5381 64.8 461000
t7t8t9 0.9864 7.879 194000
t7t10 0.9856 8.152 199000
t6 0.006 10.552 71000
t8 0.5765 23.423 570000
t6t7t9t10 0.9779 21.389 150000
t6t7t8t10 0.9905 24.424 171000
t8t9 0.9983 8.021 198000
t6t7t10 0.9729 22.568 157000
t6t7t9 0.9409 20.283 141000
t9t10 0.9947 7.914 197000
t6t9 0.9729 20.739 143000
t7 0.8719 7.165 290000
Tabla 5.16: Resultados para Rastrigin con hibridación MOS central, n = 30, a = 10 y ω = 2π
– 94 –
5.2. Resultados con funciones matemáticas
Al analizar las tablas de resultados obtenidas al optimizar la función Rastrigin, lo primero que ob-
servamos claramente en la tabla 5.14 es el mal comportamiento de la técnica t6, correspondiente a la
técnica EDA RealGaussUMDABIC. En las tablas 5.15 y 5.16, podemos ver cómo el comportamiento
de esta técnica sigue siendo muy malo, obteniendo incluso peores resultados a medida que aumentamos
las complejidad del problema. Podemos suponer, por tanto, que la función Rastrigin no es un problema
adecuado para ser resuelto por técnicas de tipo EDA, y que las técnicas de tipo genético funcionan mejor.
El resto de datos de la tabla 5.14 no son muy significativos, ya que los resultados obtenidos con el resto
de técnicas son similares en cuanto al fitness, los tiempos de ejecución y el número de evaluaciones.
Si nos centramos en las tablas 5.15 y 5.16, donde hemos aumentado la dimensión del problema y,
por tanto, su complejidad, vemos que los resultados son muy interesantes ya que, al margen de la técnica
t6 de la que ya hemos comprobado su mal funcionamiento, obtenemos una mejora notable al hibridar las
técnicas usando nuestro algoritmo MOS. De manera similar a como ocurría en el problema del Royal
Road comentado en 5.2.2, los resultados obtenidos con las técnicas individuales son mejorados de ma-
nera sustancial por las combinaciones MOS. Para ver esto con más claridad, la tabla 5.17 muestra los
resultados del fitness con técnicas individuales para el problema Rastrigin con n = 20 y n = 30 (omitimos
los resultados de t6 por no ser de interés para este análisis como hemos comentado anteriormente).
Técnicas Fitness n = 20 Fitness n = 30
t7 0.903 0.872
t8 0.975 0.577
t9 0.928 0.915
t10 0.925 0.484
Tabla 5.17: Resumen fitness técnicas individuales para función Rastrigin
Un dato interesante que podemos observar en la tabla 5.17 es cómo las técnicas t8 y t10 se desplo-
man cuando la dimensión del problema es n = 30. Estos identificadores se corresponden con las técnicas
RealBCUM y RealBCGM, que tienen en común el operador de cruce Blended Crossover (BC). El des-
plome es debido a que aumenta tremendamente la desviación en las repeticiones realizadas, obteniendo
en ocasiones resultados muy buenos y en otros muy malos. Podemos suponer que el operador de cruce
BC tiene un comportamiento muy caótico al aplicarlo a la función rastringin con n = 30, lo que pro-
voca estas anomalías. Sin embargo, como veremos a continuación, estas anomalías son controladas y
subsanadas por MOS al hibridar dicha técnica con otras más estables.
Como comparativa de la anterior, las tablas 5.18 y 5.19 muestran los resultados de las mejores 5
combinaciones de técnicas MOS para el problema Rastrigin con n = 20 y n = 30.
– 95 –
5. Análisis de resultados
Técnicas Fitness n = 20
t7t8t9t10 1.0
t6t7t8t10 1.0
t7t10 0.999
t8t10 0.999
t7t8t10 0.998
Tabla 5.18: Resumen mejores fitness para función Rastrigin con hibridación MOS y n = 20
Técnicas Fitness n = 30
t8t9 0.998
t7t8t10 0.996
t9t10 0.9947
t8t9t10 0.9917
t7t8t9t10 0.9916
Tabla 5.19: Resumen mejores fitness para función Rastrigin con hibridación MOS y n = 30
Comparando los resultados obtenidos por las mejores combinaciones MOS, y recogidos en las tablas
5.18 y 5.19, con los resultados de las técnicas individuales recogidos en la tabla 5.17, podemos observar
toda la potencia de MOS al mejorar notablemente y a través de diversas combinaciones de técnicas los
resultados individuales. Aplicando MOS a la resolución del problema de la función Rastrigin hemos
conseguido obtener unos resultados muy cercanos al óptimo, que eran impensables de obtener aplicando
métodos más tradicionales de forma separada.
En conclusión, a lo largo de esta sección hemos hecho una análisis de los resultados al aplicar MOS
con diferentes técnicas para resolver varios problemas. Hemos observado que al aplicar MOS con las
técnicas adecuadas a cada problema y, en determinadas condiciones, podemos obtener una mejora más
que notable en los resultados del cálculo del valor óptimo, sin sufrir penalizaciones adicionales. Esto
demuestra que la hibridación MOS es una aportación notable en este campo proponiendo un nuevo enfo-
que que consigue resultados superiores a los obtenidos hasta ahora, aprovechando todo el conocimiento
y desarrollo de metodologías evolutivas existentes.
– 96 –
5.3. Resultados con el TSP
5.3. Resultados con el TSP
5.3.1. Introducción al problema TSP
El problema del TSP es un problema de optimización clásico. Se trata de un problema combinatorio
popularizado por la corporación RAND en los años 40. El escenario consiste en un conjunto de ciudades
con la información relativa al coste necesario de viajar entre cada par de ciudades. El objetivo es encontrar
el camino de menor coste que recorra todas las ciudades una sola vez y vuelva al punto de partida.
Este problema tiene una gran relevancia como modelo teórico que se puede extrapolar a otros muchos
campos como la genética, la astrofísica, el diseño de semiconductores o el diseño de redes. Para más
referencias sobre el TSP, se puede consultar [17] y [19].
En los experimentos llevados a cabo para solucionar este problema hemos utilizado las técnicas
definidas en la sección 5.1.
5.3.2. Variaciones en el número de nodos y en la población
Para llevar a cabo estas pruebas, inicialmente vamos a considerar las técnicas basadas en algoritmos
genéticos definidas en la sección 4.4.2 y las técnicas basadas en algoritmos EDA definidas en la sección
4.4.3. Estas técnicas, como ya se vio, son fruto de combinar los diferentes operadores y codificaciones
disponibles en cada caso. Todos los experimentos que se describen en esta sección han sido ejecutados
con el modo de evolución central comentado en la sección 4.2.1.
Hemos aplicado estas técnicas al problema clásico del TSP, probando con tres juegos de datos dife-
rentes de varios tamaños. Concretamente, hemos utilizado los mismos que se utilizaron en [19]: Swiss42,
Brazil58 y Gr120. Para comenzar, veremos los resultados de una prueba sencilla, en la que sea ha utili-
zado un único nodo y un tamaño de población de 1000 individuos. El experimento se realizó probando
las técnicas una a una independientemente y realizando 20 repeticiones con cada una, por lo que los
resultados presentados son la media de las 20 ejecuciones.
Los resultados obtenidos en esta prueba inicial, que nos permiten observar cómo de buenas son estas
técnicas aplicadas al problema del TSP, se muestran en la tabla 5.20:
– 97 –
5. Análisis de resultados
Técnica Swiss42 Brazil58 Gr120
IntPermOXREM 0,897 0,837 0,428
RealGaussUMDABIC 0,370 0,593 0,163
IntBayesUMDABICPLSC 0,310 0,902 0,164
IntPermCXREM 0,764 0,725 0,472
RealOPCUM 0,866 0,819 0,600
IntPermOXSIM 0,918 0,847 0,590
IntPermCXSIM 0,750 0,702 0,419
Tabla 5.20: Resultados para el TSP con las 7 técnicas evolutivas, 1 nodo y 1000 individuos
Analizando la tabla 5.20, podemos observar que hay técnicas que dan mejores resultados que otras.
En general, la técnica genética que mejor resultados obtiene en este problema y estos juegos de datos es
la “IntPermOXSIM”. Las técnicas EDA podemos ver que no son muy buenas para el problema del TSP
como también se refleja en [28].
Sólo en el dataset Brazil58 han obtenido resultados interesantes, superando incluso a la mejor de las
técnicas genéticas. Sin embargo, en el resto de datasets su desempeño es paupérrimo, lo que nos lleva
a pensar que debe existir cierta disposición en los datos de este dataset que permitan este incremento
en el rendimiento de las técnicas EDA. Un futuro análisis más detallado sobre estas características sería
deseable y muy interesante.
Estos resultados se han calculado tras 20 repeticiones de una ejecución con 1000 individuos y un
solo nodo, es decir, hemos ejecutado un algoritmo secuencial, sin paralelismo ni migraciones entre islas.
En las figuras 5.3.2, 5.3.2 y 5.3.2, observamos la evolución del fitness a lo largo de las generaciones en
los tres juegos de datos utilizados para cada una de las técnicas de evolución desarrolladas.
– 98 –
5.3. Resultados con el TSP
0
0.2
0.4
0.6
0.8
1
0 50 100 150 200 250 300
Fitn
ess
Generation
Average fitness progression
IntPermOXREMRealGaussUMDABIC
IntBayesUMDABICPLSCIntPermCXREM
RealOPCUMIntPermOXSIMIntPermCXSIM
Figura 5.4: Comparativa de técnicas para el problema Swiss42
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
0 50 100 150 200 250 300 350 400 450
Fitn
ess
Generation
Average fitness progression
IntPermOXREMRealGaussUMDABIC
IntBayesUMDABICPLSCIntPermCXREM
RealOPCUMIntPermOXSIMIntPermCXSIM
Figura 5.5: Comparativa de técnicas para el problema Brazil58
– 99 –
5. Análisis de resultados
0
0.1
0.2
0.3
0.4
0.5
0.6
0 100 200 300 400 500 600 700 800
Fitn
ess
Generation
Average fitness progression
IntPermOXREMRealGaussUMDABIC
IntBayesUMDABICPLSCIntPermCXREM
RealOPCUMIntPermOXSIMIntPermCXSIM
Figura 5.6: Comparativa de técnicas para el problema Gr120
Una vez analizado el comportamiento de las técnicas en el caso más simple, vamos a introducir dos
nuevas variables y comprobar qué efectos tienen en los resultados. En este caso, vamos a aumentar el
tamaño de la población y el número de nodos, de manera que introduciremos paralelismo.
Experimentamos inicialmente con la técnica “IntPermOXSIM”, que ha demostrado ser la mejor téc-
nica en los experimentos iniciales, para realizar un estudio sobre la influencia del tamaño de la población
y el número de nodos sobre el rendimiento del algoritmo. En la tabla 5.21 se analiza el fitness obtenido
tras 20 repeticiones de ejecución utilizando diferentes combinaciones de tamaño de población y número
de nodos. Utilizaremos sólo el conjunto de datos Gr120.
1 nodo 4 nodos 8 nodos 12 nodos 16 nodos
1000 individuos 0,610 0,59 0,566 0,548 0,528
4000 individuos 0,775 0,749 0,742 0,739 0,733
8000 individuos 0,814 0,811 0,820 0,811 0,818
12000 individuos 0,858 0,839 0,848 0,854 0,836
16000 individuos 0,865 0,864 0,868 0,842 0,856
Tabla 5.21: Fitness con la técnica IntPermOXSIM en Gr120, variando nodos y población
– 100 –
5.3. Resultados con el TSP
Como vemos en la tabla 5.21, la mejora del fitness está directamente relacionada con el número de in-
dividuos de la población. Cuantos más individuos introduzcamos en la población, obtendremos mejores
resultados. Esto es bastante lógico, ya que, a mayor población, más diversidad genética y más probabili-
dad de encontrar mejores individuos. En la figura 5.7 vemos la gráfica con los resultados anteriores.
0.5
0.6
0.7
0.8
0.9
1
2000 4000 6000 8000 10000 12000 14000 16000
Fitn
ess
Poblacion
1 nodo4 nodos8 nodos
12 nodos16 nodos
Figura 5.7: Comparativa del fitness con la técnica IntPermOXSIM en Gr120
Un dato interesante que podemos observar en la tabla 5.21 y en la figura 5.7 es cómo con poblacio-
nes más pequeñas el comportamiento es mejor cuando usamos menos nodos. Esto es debido a que la
población total se divide entre los distintos nodos y, por tanto, las poblaciones de cada isla son menores
cuantos más nodos haya. Esto provoca una probable convergencia en cada isla a un óptimo local, lo que
supone una pérdida importante de exploración de soluciones. A medida que aumentamos el tamaño de la
población global, observamos cómo este efecto se mitiga. En general, podemos concluir que utilizar un
modelo de islas con diferente número de nodos no afecta sustancialmente a la calidad de las soluciones
obtenidas, mientras que lo que sí tiene una gran influencia es el tamaño de la población utilizada.
Aunque la aplicación de paralelismo a través del modelo de islas no tenga gran influencia en el cálcu-
lo del fitness en nuestro problema, vemos que sí que afecta sustancialmente a los tiempos de ejecución,
como se puede ver en la tabla 5.22 y en la figura 5.8, que se corresponden a los tiempos de ejecución
correspondientes a los experimentos presentados anteriormente en la tabla 5.21 y en la figura 5.7.
– 101 –
5. Análisis de resultados
1 nodo 4 nodos 8 nodos 12 nodos 16 nodos
1000 individuos 41 16 8 7 4
4000 individuos 348 77 43 32 19
8000 individuos 1208 172 80 58 33
12000 individuos 2361 330 117 93 50
16000 individuos 2189 502 198 122 79
Tabla 5.22: Tiempo en segundos con la técnica IntPermOXSIM en Gr120, variando el número de nodos
y de individuos
0
500
1000
1500
2000
2500
2000 4000 6000 8000 10000 12000 14000 16000
Tie
mpo
Poblacion
1 nodo4 nodos8 nodos
12 nodos16 nodos
Figura 5.8: Comparativa del tiempo con la técnica IntPermOXSIM en Gr120
De la tabla 5.22 y la figura 5.8 podemos extraer la conclusión de la gran ventaja que aporta el pa-
ralelismo a los tiempos de ejecución. Vemos cómo, a medida que aumentamos el número de nodos,
disminuye sustancialmente el tiempo de ejecución incluso con poblaciones grandes. Es muy notable la
enorme diferencia que existe entre la ejecución en un solo nodo con respecto a la ejecución en 4 nodos.
– 102 –
5.3. Resultados con el TSP
5.3.3. Resultados con hibridación de técnicas basadas en GAs
Nuestro siguiente experimento se apoya en las tesis desarrolladas en [19]. Intentaremos mejorar los
resultados obtenidos hasta ahora usando el concepto de hibridación de técnicas que propone MOS.
La tabla 5.23 muestra los resultados obtenidos tras hacer experimentos con todas las combinaciones
posibles de hibridación de técnicas MOS GA. En estos resultados utilizaremos la nomenclatura abreviada
definida en la tabla 5.3. Los experimentos se han realizado utilizando 16 nodos, con poblaciones de
1000 individuos por nodo y con medias de 20 repeticiones independientes de cada ejecución. En este
experimente hemos ejecutado siguiendo el modelo evolutivo central.
Técnicas Swiss42 Brazil58 Gr120
t0 0.951 0.898 0.723
t0t1 0.954 0.948 0.829
t0t1t2 0.959 0.945 0.82
t0t1t2t3 0.974 0.948 0.871
t0t1t2t3t4 0.963 0.949 0.863
t0t1t2t4 0.956 0.940 0.831
t0t1t3 0.966 0.955 0.87
t0t1t3t4 0.969 0.955 0.859
t0t1t4 0.963 0.940 0.837
t0t2 0.945 0.897 0.706
t0t2t3 0.978 0.943 0.876
t0t2t3t4 0.969 0.952 0.861
t0t2t4 0.925 0.883 0.716
t0t3 0.987 0.956 0.878
t0t3t4 0.981 0.950 0.881
t0t4 0.926 0.890 0.725
t1 0.929 0.927 0.752
t1t2 0.898 0.914 0.726
t1t2t3 0.968 0.950 0.858
t1t2t3t4 0.970 0.942 0.868
t1t2t4 0.938 0.938 0.769
t1t3 0.980 0.947 0.852
t1t3t4 0.958 0.949 0.881
– 103 –
5. Análisis de resultados
t1t4 0.930 0.931 0.799
t2 0.938 0.867 0.685
t2t3 0.974 0.957 0.836
t2t3t4 0.974 0.946 0.867
t2t4 0.917 0.754 0.547
t3 0.977 0.951 0.86
t3t4 0.973 0.947 0.878
t4 0.806 0.784 0.54
Fitness medio 0.950 0.922 0.789
Tabla 5.23: Resultados para el TSP con hibridación MOS central de técnicas GA
En la figura 5.9 vemos de forma gráfica los resultados recogidos en la tabla 5.23. Podemos observar
que el comportamiento de las combinaciones de técnicas es, en general, bastante independiente del con-
junto de datos utilizado, ya que, en general, siguen un patrón similar. Esto nos lleva a concluir que, para
este tipo de evolución en el problema del TSP, existen combinaciones de técnicas en general buenas,
frente a otras combinaciones que son bastante peores. Esta diferencia entre el desempeño de unas y otras
técnicas se acrecienta a medida que la complejidad del problema a resolver aumenta.
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
0,5
0,6
0,7
0,8
0,9
1
swiss42 central
brazil58 central
gr120 central
Figura 5.9: Comparativa de los resultados para el TSP con hibridación MOS central
– 104 –
5.3. Resultados con el TSP
5.3.3.1. Análisis de la participación y la calidad
Uno de los aspectos más interesantes desarrollados en MOS es el ajuste de la participación de las
técnicas en función de la calidad, como ya desarrollamos en el capítulo 4, para mejorar el fitness de los in-
dividuos de la manera más rápida posible. Vamos a ver el comportamiento de la calidad y la participación
de las técnicas a lo largo de las generaciones. Utilizaremos la combinación de técnicas que mejor resul-
tados ha dado, que se compone de las técnicas IntPermOXREM, IntPermOXSIM e IntPermCXREM. En
la figura 5.10 podemos ver las gráficas que muestran la evolución de la participación y la calidad para
esta combinación, junto con el fitness medio obtenido. Estos resultados se han calculado con las medias
de 20 repeticiones del mismo experimento.
0.25
0.5
0.75 0.871732
1
0 100 200 300 400 500 600 700
Fitn
ess
Generation
Average fitness progression
Max
0
0.25
0.5
0.75
1
0 100 200 300 400 500 600 700Par
ticip
atio
n F
unct
ion
Generation
Participation progression
IntPermOXREMIntPermOXSIM
IntPermCXREM
0
0.25
0.5
0.75
1
0 100 200 300 400 500 600 700
Qua
lity
Fun
ctio
n
Generation
Quality progression
IntPermOXREMIntPermOXSIM
IntPermCXREM
Figura 5.10: Evolución de la participación y la calidad. Combinación de 3 técnicas con el TSP gr120
Vemos cómo claramente la técnica que mejor resultados parece que obtiene es la IntPermOXSIM, ya
que es la que más calidad presenta y, por tanto, la que mayor participación recibe. En la ejecución de estas
pruebas se ha decidido configurar el algoritmo para que todo técnica tenga siempre, al menos, un mínimo
de participación, en este caso del 10 %. Vemos que las técnicas IntPermOXREM e IntPermCXREM
acaban teniendo este porcentaje mínimo de participación porque no consiguen alcanzar tanta calidad.
– 105 –
5. Análisis de resultados
Viendo la gráfica anterior, sería razonable pensar que la técnica IntPermOXSIM por sí sola podría
obtener los mismos resultados, ya que parece que es la que más calidad tiene y la que hace que el fitness
se incremente. Sin embargo, como se puede ver en la tabla 5.23, esto no es así, ya que esta combinación
de técnicas mejora los resultados obtenidos en comparación con la ejecución de técnicas individuales.
Esto es debido a que, aunque haya técnicas que sean claramente mejores que otras para este problema,
el hecho de ejecutar con varias técnicas amplía la capacidad de búsqueda del algoritmo, aumentando la
diversidad de los individuos generados y esto, a la larga, permite buscar y encontrar mejores resultados.
Al final, el ajuste dinámico de la participación, en cualquier caso, permite tender a evolucionar hacia los
mejores individuos con las mejores técnicas.
Es muy interesante hacer un análisis del comportamiento de la función de participación. Vemos
cómo aproximadamente hasta la generación 200 la participación de las técnicas va variando hasta que
se estanca, en beneficio de la técnica IntPermOXSIM y en detrimento de las otras. Sin embargo, la
evolución de la calidad es mucho más suave y equitativa, pese a tender a crecer más rápido la de la
técnica IntPermOXSIM. Esto es debido a que los individuos generados por la técnica IntPermOXSIM,
que claramente es la mejor, muchas veces serán utilizados como los padres en los cruces realizados
por las otras técnicas en generaciones posteriores. Esto hace que la calidad introducida por la técnica
IntPermOXSIM se herede en estos hijos y, por tanto, influya en la calidad de las otras técnicas. La
función de participación, sin embargo, al utilizar un mecanismo de bonificación no es tan susceptible
de suavizar estas diferencias y en menos generaciones bonifica notablemente la técnica IntPermOXSIM,
penalizando las otras.
Un variación interesante en la implementación podría ser suavizar el comportamiento de la función
de participación para que siga un patrón más acorde a la función de calidad y viceversa, desarrollar un
mecanismo de estimación de la calidad que destile de manera más fina la calidad introducida por cada
técnica.
Como ya comentamos en los experimentos desarrollados, hasta ahora se ha fijado un mínimo porcen-
taje de participación de las técnicas, al 10 %. Veamos ahora el comportamiento al levantar esta restricción
y no fijar ningún porcentaje mínimo de participación. Como antes los resultados expuestos se han calcu-
lado con las medias de 20 repeticiones del experimento.
– 106 –
5.3. Resultados con el TSP
0.25
0.5
0.75 0.859585
1
0 100 200 300 400 500 600
Fitn
ess
Generation
Average fitness progression
Max
0
0.25
0.5
0.75
1
0 100 200 300 400 500 600Par
ticip
atio
n F
unct
ion
Generation
Participation progression
IntPermOXREMIntPermOXSIM
IntPermCXREM
0 0.2 0.4 0.6 0.7 0.9 1.1
0 100 200 300 400 500 600
Qua
lity
Fun
ctio
n
Generation
Quality progression
IntPermOXREMIntPermOXSIM
IntPermCXREM
Figura 5.11: Evolución de la participación y la calidad para una combinación de 3 técnicas en el TSP
gr120 sin porcentaje mínimo de participación
Como se puede observar en la gráfica de la figura 5.11, los resultados globales en el cálculo del fitness
son peores en el caso de no fijar un mínimo de la participación. De esta manera, vemos la importancia
de mantener en cierta medida una mínima influencia de las técnicas que no son tan buenas para obtener
mejores resultados.
Para finalizar esta sección, podemos concluir que la combinación de técnicas con ajuste dinámico
de la participación supone una mejora notable frente a la ejecución de técnicas individuales, por muy
buenas que éstas sean. También podemos concluir que es conveniente fijar un mínimo de participación
para que ninguna técnica llegue a extinguirse, y aprovechar al máximo las bondades de cada una.
5.3.4. Evolución central versus autonómica
En esta sección vamos a comentar los resultados obtenidos al ejecutar nuestro algoritmo intentando
resolver el problema del TSP, pero en este caso utilizando la modalidad de evolución autonomic, descrita
en la sección 4.2.2.
– 107 –
5. Análisis de resultados
Técnicas Swiss42 Brazil58 Gr120
t0 0.952 0.903 0.743
t0t1 0.964 0.938 0.775
t0t1t2 0.957 0.944 0.778
t0t1t2t3 0.977 0.951 0.853
t0t1t2t3t4 0.952 0.937 0.856
t0t1t2t4 0.941 0.924 0.795
t0t1t3 0.964 0.945 0.853
t0t1t3t4 0.957 0.941 0.871
t0t1t4 0.949 0.937 0.792
t0t2 0.933 0.897 0.731
t0t2t3 0.973 0.948 0.862
t0t2t3t4 0.965 0.949 0.871
t0t2t4 0.919 0.88 0.689
t0t3 0.988 0.951 0.866
t0t3t4 0.967 0.938 0.866
t0t4 0.93 0.861 0.689
t1 0.925 0.932 0.73
t1t2 0.895 0.928 0.718
t1t2t3 0.962 0.939 0.862
t1t2t3t4 0.957 0.948 0.861
t1t2t4 0.917 0.915 0.738
t1t3 0.974 0.946 0.861
t1t3t4 0.964 0.95 0.858
t1t4 0.927 0.939 0.738
t2 0.915 0.866 0.695
t2t3 0.969 0.939 0.871
t2t3t4 0.972 0.943 0.858
t2t4 0.906 0.798 0.59
t3 0.977 0.948 0.853
t3t4 0.974 0.944 0.878
t4 0.815 0.768 0.544
Fitness medio 0.945 0.919 0.781
Tabla 5.24: Fitness para el TSP con hibridación MOS autonomic de técnicas GA
– 108 –
5.3. Resultados con el TSP
La tabla 5.24 muestra los resultados obtenidos con este modelo de ejecución, MOS autonomic, com-
binando las diferentes técnicas en todas sus posibles combinaciones y resolviendo el problema con 3
juegos de datos distintos, los mismos que usamos anteriormente en la ejecución central.
La gráfica de la figura 5.12 recoge de un modo gráfico los resultados expuestos en la tabla 5.24. Como
podemos comprobar, al igual que en el caso central hay combinaciones de técnicas que se comportan
mejor que otras.
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
0,5
0,6
0,7
0,8
0,9
1
swiss42 autonomic
brazil58 autonomic
gr120 autonomic
Figura 5.12: Comparativa del fitness para el TSP con hibridación MOS autonomic
La pregunta que se nos plantea es saber si el modo de ejecución autonomic aporta alguna ventaja
frente al modo de ejecución central. Para ello realizaremos una comparativa, uno a uno, de los resultados
obtenidos con los dos tipos de evolución para cada combinación de técnicas y para cada uno de los tres
juegos de datos.
Las figuras 5.13, 5.14 y 5.15 recogen las comparativas del fitness, agrupando los resultados con cada
juego de datos en cada gráfica.
– 109 –
5. Análisis de resultados
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,9
1
swiss42 central
swiss42 autonomic
Figura 5.13: Comparativa del fitness para el TSP swiss42 con evolución MOS central frente autonomic
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,9
1
brazil58 central
brazil58 autonomic
Figura 5.14: Comparativa del fitness para el TSP brazil58 con evolución MOS central frente autonomic
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,9
1
gr120 central
gr120 autonomic
Figura 5.15: Comparativa del fitness para el TSP gr120 con evolución MOS central frente autonomic
Como podemos observar, en general, el fitness es similar en ambos modelos evolutivos en las tres
gráficas, con lo que el método autonomic no supone ninguna ventaja en este sentido.
– 110 –
5.3. Resultados con el TSP
5.3.4.1. Análisis de tiempos
Hemos comprobado que no obtenemos ninguna ganancia desde el punto de vista del cálculo del
fitness cuando ejecutamos con el modelo autonomic. Ahora bien, como los resultados no son peores que
en el modelo central, podemos hacer un estudio de los tiempos de ejecución con el modelo autonomic, en
comparación al modelo central. Si los tiempos fuesen inferiores esto supondría una ventaja interesante a
la hora de resolver más rápidamente el mismo problema con resultados equivalentes.
Las gráficas 5.16, 5.17 y 5.18 muestran una comparativa de los tiempos de ejecución en segundos
para las ejecuciones con diferentes combinaciones de técnicas con el modelo central y autonomic. Cada
gráfica refleja la ejecución con un juego de datos diferente.
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
5
7
9
11
13
15
17
19
21
23
swiss42 central
swiss42 autonomic
Figura 5.16: Comparativa del tiempo para el TSP swiss42 con evolución MOS central frente autonomic
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
5
10
15
20
25
30
35
40
45
50
brazil58 central
brazil58 autonomic
Figura 5.17: Comparativa del tiempo para el TSP brazil58 con evolución MOS central frente autonomic
– 111 –
5. Análisis de resultados
t0t0t1
t0t1t2t0t1t2t3
t0t1t2t3t4t0t1t2t4
t0t1t3t0t1t3t4
t0t1t4t0t2
t0t2t3t0t2t3t4
t0t2t4t0t3
t0t3t4t0t4
t1t1t2
t1t2t3t1t2t3t4
t1t2t4t1t3
t1t3t4t1t4
t2t2t3
t2t3t4t2t4
t3t3t4
t4
5
15
25
35
45
55
65
75
85
95
105
gr120 central
gr120 autonomic
Figura 5.18: Comparativa del tiempo para el TSP gr120 con evolución MOS central frente autonomic
Como podemos observar en las gráficas para los juegos de datos swiss42 y brazil58 los tiempos son
notablemente más altos, y por lo tanto peores, en la ejecución con el modelo autonomic. Sin embargo,
en la gráfica de la figura 5.15, que recoge los resultados para el conjunto de datos gr120, vemos que en
muchos los tiempos para la ejecución con el modelo evolutivo autonomic son inferiores.
Por lo tanto, pese a obtener resultados similares en cuanto al cálculo del fitness, el modelo de evolu-
ción autonomic puede resultarnos interesante para reducir los tiempos de ejecución en algunos conjuntos
de datos. Por los experimentos realizados, observamos cómo los tiempos mejoran en el caso autonomic
cuando los conjuntos de datos son más grandes.
– 112 –
Parte V
Conclusiones y líneas futuras
Capítulo 6
Conclusiones y líneas futuras
En este último capítulo vamos a presentar las conclusiones a las que se han llegado en la realización
de este proyecto y a trazar unas líneas futuras de investigación para extender el presente trabajo.
6.1. Conclusiones
Durante el desarrollo de este proyecto hemos conseguido diseñar e implementar con éxito un algo-
ritmo híbrido evolutivo que tuviese las características definidas en los objetivos del capítulo 1.1.
Como era nuestra intención, la plataforma MOS da soporte a diferentes técnicas evolutivas, como se
desarrolló en la sección 4.2. Además, es capaz de orquestar estas técnicas usando el concepto de calidad,
tal y como se vio en la sección 4.4.
Por tanto, la arquitectura MOS diseñada permite un sencillo diseño de nuevas técnicas evolutivas,
suministrando una arquitectura muy flexible con grandes posibilidades de extensión incorporando nuevos
métodos evolutivos.
Además, en el capítulo 5 hemos hecho un profundo análisis del comportamiento del algoritmo híbrido
evolutivo MOS aplicado a diferentes problemas y con diferentes configuraciones.
Los resultados obtenidos han sido más que satisfactorios, obteniendo mejoras con una amplia va-
riedad de configuraciones al hibridar 2 o más técnicas MOS para resolver un problema. Durante los
experimentos realizados para este proyecto, además, hemos extraído ciertas conclusiones generales so-
bre los algoritmos evolutivos. Una de las conclusiones más interesantes es la necesidad de introducción
de paralelismo a la hora de obtener resultados en un tiempo razonable en problemas grandes y comple-
jos. Como hemos observado a la hora de resolver problemas reales, el paralelismo va de la mano de los
algoritmos evolutivos con el fin de obtener resultados en tiempos razonables.
– 115 –
6. Conclusiones y líneas futuras
Por otro lado, hemos constatado que el paralelismo a través del modelo de islas, pese a aportarnos
notables ventajas en la reducción de los tiempos de ejecución, no tiene un efecto significativo en la
mejora del cálculo del fitness, por lo menos en el caso del problema del viajante, que es en el que hemos
aplicado esta aproximación paralela.
En cualquier caso, como conclusión global del desarrollo de este proyecto podemos afirmar, apo-
yándonos en los resultados obtenidos, que el algoritmo evolutivo MOS que hemos desarrollado supone
una mejora a los algoritmos evolutivos tradicionales, siendo capaz de extraer lo mejor de cada uno de
los algoritmos disponibles para obtener mejores resultados que los obtenidos hasta la fecha mediante
técnicas individuales.
6.2. Líneas futuras
La arquitectura MOS propone una plataforma que ya ha demostrado sus bondades, pero que puede
ser continuamente extendida y mejorada con el fin de obtener aún mejores resultados.
Una de las virtudes de MOS es lo relativamente sencillo que resulta actualizar o mejorar alguno de
sus componentes.
Como líneas futuras de investigación en torno a MOS proponemos el desarrollo de nuevas técnicas
evolutivas, ya sea como nuevas configuraciones de los modelos existentes o como el desarrollo de nuevos
modelos evolutivos que puedan ser incorporados al abanico de posibilidades que ofrece MOS. Concre-
tamente, sería de mucho interés el desarrollo de técnicas basadas en Particle Swarm Optimization (PSO)
y evolución diferencial, que han demostrado ser muy eficaces en la optimización de funciones matemá-
ticas en los últimos años, así como la incorporación de nuevos operadores para las técnicas genéticas ya
existentes.
Otro aspecto a estudiar sería la introducción de métodos que permitieran el diseño y la generación
automática de técnicas usando diferentes configuraciones disponibles. De esta manera se podría realizar
un análisis más preciso de qué configuraciones son las más adecuadas para resolver cada problema.
Por otro lado, sería interesante seguir desarrollando procedimientos de estimación de la calidad de
una técnica basados en diferentes medidas como la diversidad, la edad, etc.
Otro aspecto interesante en el que profundizar sería un estudio más detallado de las ventajas de la
variante evolutiva MOS autonomic con conjuntos de datos grandes.
Por último, sería de mucho interés aplicar MOS a nuevos problemas más complejos y más cercanos
a la industria.
– 116 –
Bibliografía
[1] Gene Amdahl. Validity of the single processor approach to achieving large-scale computing capa-
bilities. AFIPS Conference Proceedings, 30:483–485, 1967. [Citado en pág. 18.]
[2] S. Baluja and S. Davies. Combining multiple optimization runs with optimal dependency trees.
Technical Report CMU-CS-97-157, Carnegie Mellon, Pittsburgh, PA, 1997. [Citado en pág. 45.]
[3] Shumeet Baluja. Population-based incremental learning: A method for integrating genetic search
based function optimization and competitive learning,. Technical Report CMU-CS-94-163, Carne-
gie Mellon, Pittsburgh, PA, 1994. [Citado en pág. 45.]
[4] P. Bosman and E. de Jong. Combining gradient techniques for numerical multi-objective evolu-
tionary optimization. In Proceedings of the Genetic and Evolutionary Computation Conference
GECCO-06, pages 627–634, Seattle, Washington, USA, 2006. ACM press. [Citado en pág. 54.]
[5] David E. Culler and Jaswinder Pal Singh. Parallel computer architecture: a hardware/software
approach. Morgan Kaufmann, 1999. [Citado en págs. 15 y 20.]
[6] C. Darwin. On the Origin of Species by Means of Natural Selection. John Murray, London, 1859.
[Citado en págs. 3, 31 y 36.]
[7] Jeremy S. de Bonet, Charles L. Isbell, and Paul Viola. MIMIC: Finding optima by estimating pro-
bability densities. In Michael C. Mozer, Michael I. Jordan, and Thomas Petsche, editors, Advances
in Neural Information Processing Systems, volume 9, page 424. The MIT Press, 1997.
[Citado en pág. 45.]
[8] Pedro de Miguel Anasagasti. Fundamentos de los computadores. Thompson, 1988.
[Citado en pág. 15.]
[9] P. Díaz. Diseño e implementación de una librería de algoritmos evolutivos paralelos. Master’s
thesis, Universidad Politécnica de Madrid, 2005. [Citado en págs. 31, 48 y 58.]
– 117 –
Bibliografía
[10] R. Etxeberria, P. Larrañaga, and J. Lozano. Combinatorial optimization by learning and simulation
of bayesian networks, 2000. [Citado en pág. 45.]
[11] Michael J. Flynn. Some computer organizations and their effectiveness. IEEE Trans. Comput,
pages 948–960, 1972. [Citado en pág. 10.]
[12] L.J. Fogel, A.J. Owens, and M.J. Walsh. Artificial Intelligence through Simulated Evolution. John
Wiley, New York, USA, 1966. [Citado en pág. 32.]
[13] Andreas Griewank. Evaluating Derivatives: Principles and Techniques of Algorithmic Differentia-
tion. Society for Industrial and Applied Mathematics, 2000. [Citado en pág. 78.]
[14] John L. Gustafson. Reevaluating amdahl’s law. Communications of the ACM, 31(5):532–533, 1988.
[Citado en pág. 19.]
[15] J.H. Holland. Adaptation in natural and artificial systems. MI: University of Michigan Press, 1975.
[Citado en págs. 4, 32 y 78.]
[16] Kenneth A. De Jong. Analysis of the behavior of a class of genetic adaptive systems. Engineering,
College of - Technical Reports, 185, 1975. [Citado en págs. 39 y 54.]
[17] P. Larrañaga, C. Kuijpers, R. Murga, I. Inza, and S. Dizdarevic. Genetic algorithms for the traveling
salesman problem: A review of representations and operators. Articial Intelligence Review, 13:129–
170, 1999. [Citado en págs. 32, 41 y 97.]
[18] P. Larrañaga and J.A. Lozano. Estimation of Distribution Algorithms. A New Tool for Evolutionary
Computation. Kluwer Academic Publishers, 2001. [Citado en pág. 45.]
[19] A. LaTorre, J.M. Peña, V. Robles, and S. Muelas. Using multiple offspring sampling to guide
genetic algorithms to solve permutation problems. Aceptado en GECCO, 2008.
[Citado en págs. 97 y 103.]
[20] G. Lin, L. Kang, Y. Chenand, B.McKay, and R.Sarker. A self-adaptive mutations with multi-
parent crossover evolutionary algorithm for solving function optimization problems. In Advances
in computation and Intelligence: Proceedings of the Second Internacional Symposium ISICA-07,
pages 157–168, Wuhan, China, 2007. Springer-Verlag. [Citado en pág. 54.]
[21] H. Mühlenbein. The equation for the response to selection and its use for prediction, volume 5,
pages 303–346. MIT Press, 1998. [Citado en pág. 45.]
[22] J. Pearl. Probabilistic Reasoning in Intelligent Systems. Morgan-Kaufmann, 1988.
[Citado en pág. 44.]
– 118 –
Bibliografía
[23] Martin Pelikan, David E. Goldberg, and Erick Cantú-Paz. BOA: The Bayesian optimization algo-
rithm. In Wolfgang Banzhaf, Jason Daida, Agoston E. Eiben, Max H. Garzon, Vasant Honavar,
Mark Jakiela, and Robert E. Smith, editors, Proceedings of the Genetic and Evolutionary Compu-
tation Conference GECCO-99, volume I, pages 525–532, Orlando, FL, 13-17 1999. Morgan Kauf-
mann Publishers, San Fransisco, CA. [Citado en pág. 45.]
[24] Martin Pelikan and Heinz Mühlenbein. The bivariate marginal distribution algorithm. In R. Roy,
T. Furuhashi, and P. K. Chawdhry, editors, Advances in Soft Computing - Engineering Design and
Manufacturing, pages 521–535, London, 1999. Springer-Verlag. [Citado en pág. 45.]
[25] L. Van Pit. Parallel genetic algorithms. Master’s thesis, Leiden University, 1995.
[Citado en pág. 46.]
[26] I. Rechenberg. Evolutionsstrategie: Optimierung technischer Systeme nach Prinzipien der biolo-
gischen Evolution. PhD thesis, Technical University of Berlin, 1973. [Citado en pág. 32.]
[27] I. Rechenberg. Evolutionsstrategie. Frommann Holzboog, 1994. [Citado en pág. 32.]
[28] V. Robles, J.M. Peña, P.Larrañaga, M.S. Pérez, and V. Herves. GA-EDA: A New Hybrid Cooperative
Search Evolutionary Algorithm, volume 192, pages 187–219. Springer, 2006. [Citado en pág. 98.]
[29] R.Salomon. The influence of different codings schemes on the computacional complexity of genetic
algorithms in function optimization, pages 227–235. Springer-Verlag, Berlin, 1996.
[Citado en pág. 54.]
[30] Hans-Paul Schwefel. Numerical Optimization of Computer Models. Wiley, Chichester, 1981.
[Citado en pág. 32.]
[31] R. D. Shachter and C. R. Kenley. Gaussian influence diagrams. Management Science, 35:527–550,
1989. [Citado en pág. 44.]
[32] J. Stender. Parallel Genetic Algorithm: Theory and Applications. IOS Press, 1993.
[Citado en pág. 46.]
[33] Gilbert Syswerda and Jeff Palmucci. The application of genetic algorithms to resource scheduling.
In ICGA, pages 502–508, 1991. [Citado en pág. 40.]
[34] D. Thierens. An adaptative pursuit strategy for allocating operator probabilities. In Proceedings of
the Genetic and Evolutionary Computation Conference GECCO-05, pages 1539–1546, New York,
USA, 2005. ACM press. [Citado en pág. 54.]
– 119 –
Bibliografía
[35] J. Whitacre, T. Pham, and R.Sarker. Credit assignment in adaptative evolutionary algorithms. In
Proceedings of the Genetic and Evolutionary Computation Conference GECCO-06, pages 1353–
1360, Seattle, Washington, USA, 2006. ACM press. [Citado en pág. 54.]
– 120 –