Carlos José Quijano Valencia
Miller Alexis Quintero García
Kelly Yojana Ospina Correa
Mateo Sebastián Mora Montero
Stiven
Julio Doval
Profesor: Juan David Ospina Arango
Monitor: Andrés Mauricio Zapata Rincón
Universidad Nacional de Colombia, Sede Medellín
Mayo 2 del 2025
Enlace a repositorio GitHub: https://github.com/Straver00/RNA_2025-1
A lo largo del camino de desarrollo e innovación tecnológica con base fundamental en las matemáticas, los problemas asociados a optimización han sido muy comunes, esto entendiendo que la humanidad siempre ha buscado la mejor solución posible, gastando la menor cantidad de recursos, ya que esto es importante para sostenibilidad y el progreso. Es en este contexto que se han desarrollado múltiples técnicas y algoritmos para optimizar procesos, los cuales por su naturaleza, no funcionan todos de igual forma en contextos diferentes, por ello es necesario poner a prueba esta clase de métodos de optimización.
Por ello este trabajo se centra en estudiar, analizar y comparar algoritmos diferentes, específicamente, uno clásico y famoso usado en múltiples situaciones con una base analítica, tal y como lo es el descenso por gradiente con condición inicial aleatoria; también otros de ingenio heurístico con inspiración en procesos observados en la naturaleza, tales como los algoritmos genéticos (evolutivos), los enjambres de partículas, la evolución diferencial y las colonias de hormigas. Para dicho fin, este trabajo se ha centrado en 2 ejes:
El objetivo será entonces por medio de estos ejes principales, comprender la importancia, aplicabilidad y ventajas de estos algoritmos, reconociendo su papel fundamental en aplicaciones tecnológicas modernas como la inteligencia artificial, la logística y la ingeniería de sistemas complejos.
Se seleccionaron las siguientes funciones de prueba para evaluar los diferentes algoritmos de optimización:
La función de Rastrigin se define a continuación con la ecuación (1) según ‘Wikipedia contributors; Rastrigin function’:
\[ f(\mathbf{x}) = An + \sum_{i=1}^{n} \left[ x_i^2 - A \cos(2\pi x_i) \right]\, \forall\,\, x_i \in [-5.12,\ 5.12]\qquad (1) \]
donde \(A=10\) y \(x_i \in [-5.12, 5.12]\). Dicha función (1) cuenta con su mínimo global en \(X = [0,0,...,0]\) con un valor de \(f(\mathbf{x}) = 0\).
Luego, la de Rosenbrock se define como describe ahora la ecuación (2), tomada de ‘Wikipedia contributors; Rosenbrock function’:
\[ f(\mathbf{x}) = \sum_{i=1}^{n-1} \left[ 100(x_{i+1} - x_i^2)^2 + (1 - x_i)^2 \right]\, \forall\,\, x_i \in [-\infty,\ \infty]\qquad (2) \] Y esta función (2) cuenta con su mínimo global en \(X = [1,1,...,1]\) con un valor de \(f(\mathbf{x}) = 0\).
Ahora bien, la función de Rastrigin tiene un dominio limitado, mientras la de Rosenbrock tiene como dominio los reales, sin embargo, ambas las vamos a trabajar en el espacio de búsqueda de Rastrigin, entendiendo que ambos mínimos globales están en dicho espacio, y ampliarlo es incrementar el costo computacional innecesariamente sin motivo alguno para el ejercicio de examinar los métodos de optimización.
Veamos ahora gráficamente como es la función de Rastrigin con entrada y salida 2D → 3D.Fig.1 Superficie de Rastrigin
Igualmente un mapa de calor con curvas de nivel para entender
desde otra perspectiva la función.
Fig.2 Heatmap de Rastrigin
Ahora un gráfico de curvas de nivel simple para la función de
Rastrigin.
Fig.3 Levelplot de Rastrigin
Hacemos lo mismo con la función de Rosenbrock para tener una
idea general.
Fig.4 Superficie de Rosenbrock
Fig.5 Heatmap de Rosenbrock
Fig.6 Levelplot de Rosenbrock
Con las funciones presentadas y teniendo claro su topografía,
además del espacio de búsqueda; procedemos con las optimizaciones.
NOTA: Para las funciones 3D → 4D no se hacen representaciones, debido a la abstracción fuera de nuestra percepción geométrica tridimensional.
El descenso de gradiente es un algoritmo de optimización determinista que busca minimizar (o maximizar) una función ajustando iterativamente sus variables en la dirección del gradiente negativo. Es ampliamente utilizado en matemáticas, ingeniería y aprendizaje automático como un método clásico. Tiene hiperparámetros como:
En esta parte se realizará la optimización de las anteriores funciones en dos y tres dimensiones, usando el método de descenso por gradiente, el cual consiste en recorrer la función dando pasos pequeños en la dirección en donde la función decrece más rápido.
En este caso debido a la complejidad de las funciones de prueba se realizaron algunas modificaciones al método simple, por ejemplo; si la distancia entre el punto y la actualización crece demasiado o el método no converge con cierto número de iteraciones, se reinicia el algoritmo con un nuevo punto aleatorio o el mejor punto encontrado hasta el momento, respectivamente. Esto hace que el método sea menos propenso a quedarse en mínimos locales y tenga más chances de llegar hasta el mínimo global.
Comenzamos con la solución para 2 dimensiones base, o sea f(x,y):
## Reinicio número: 1 Iniciando desde: -3.22680565834045, 2.07231012821198 Valor: 24.26904
## No hay mejora significativa en 5000 iteraciones. Reiniciando desde el mejor punto encontrado.
## Reinicio número: 2 Iniciando desde: -1.02371988293758, 0.0575919115306958 Valor: 1.809776
## No hay mejora significativa en 5000 iteraciones. Reiniciando desde el mejor punto encontrado.
## Reinicio número: 3 Iniciando desde: -1.01329607602703, -0.00972459521248048 Valor: 1.0804
## No hay mejora significativa en 5000 iteraciones. Reiniciando desde el mejor punto encontrado.
## Reinicio número: 4 Iniciando desde: -1.01329607602703, -0.00972459521248048 Valor: 1.0804
## No hay mejora significativa en 5000 iteraciones. Reiniciando desde el mejor punto encontrado.
## Reinicio número: 5 Iniciando desde: -1.01329607602703, -0.00972459521248048 Valor: 1.0804
## No hay mejora significativa en 5000 iteraciones. Reiniciando desde el mejor punto encontrado.
## No se logró la convergencia después de 5 reinicios.
## La mejor solución hallada está en (x, y) = (-1.01329607602703, -0.00972459521248048).
## Con un valor óptimo de 1.08040041990205.
Veamos como se ve la solución hallada en un gráfico de curvas de nivel, donde la solución óptima real está representada como un punto verde y la del método de optimización con un punto rojo:
Fig.7 GD Rastrigin
Se puede ver que a pesar de todos los reinicios e iteraciones del método, este se estancó en un mínimo local.
Veamos ahora para 3 dimensiones base, o sea f(x,y,z):
## Reinicio número: 1 Iniciando desde: 3, 3, 3 Valor: 27
## No hay mejora significativa en 5000 iteraciones. Reiniciando desde el mejor punto encontrado.
## Reinicio número: 2 Iniciando desde: 4.58437385466581e-05, 4.58437385466581e-05, 4.58437385466581e-05 Valor: 1.250851e-06
## Convergió en 6113 iteraciones (reinicio 1 )
## La mejor solución hallada está en:
## (x, y, z) = (4.58437385466581e-05, 4.58437385466581e-05, 4.58437385466581e-05)
## Con un valor óptimo de 1.25085121283064e-06
Ese valor óptimo hallado en 3D, si analizamos las coordenadas (x, y, z) vemos que se aproxima al mínimo global, por lo que en esta ocasión el método lo hizo bien.
Aplicamos ahora si la optimización en 2D.
## Reinicio número: 1 Iniciando desde: -3.22680565834045, 2.07231012821198 Valor: 6973.367
## La distancia es Inf. Reiniciando con un nuevo punto de inicio aleatorio.
## Reinicio número: 2 Iniciando desde: 0.733263348229229, -3.31948079634458 Valor: 1487.836
## Convergió en 19788 iteraciones (reinicio 1 )
## La mejor solución hallada está en (x, y) = (0.99988826932461, 0.999776104001655)
## Con un valor óptimo de 1.25037364638396e-08
Veamos gráficamente el resultado para este caso, siguiendo la convención anterior para el óptimo real y el óptimo del método.
Fig.8 GD Rosenbrock
En este caso si convergió bien el método del gradiente con un punto inicial aletorio, posiblemente la topografía de la función de Rosenbrock no atrapa tan fácilmente con un mínimo local, o el punto inicial favoreció el proceso.
Ejecutemos ahora el caso 3D.
## Reinicio número: 1 Iniciando desde: -3.22680565834045, 2.07231012821198, 0.750861668586731 Valor: 8230.232
## La distancia es Inf. Reiniciando con un nuevo punto de inicio aleatorio.
## Reinicio número: 2 Iniciando desde: -3.31948079634458, 4.43839338840917, 4.43474958650768 Valor: 27661.62
## La distancia es Inf. Reiniciando con un nuevo punto de inicio aleatorio.
## Reinicio número: 3 Iniciando desde: -3.70841023279354, 3.33448815625161, -0.319814844988286 Valor: 23964.93
## La distancia es Inf. Reiniciando con un nuevo punto de inicio aleatorio.
## Reinicio número: 4 Iniciando desde: 0.499837417155504, 0.526740669738501, -2.6110524055548 Valor: 842.4896
## Convergió en 17095 iteraciones (reinicio 3 )
## La mejor solución hallada está en:
## (x, y, z) = (0.999954281647075, 0.999908391106169, 0.999816354226281)
## Con un valor óptimo de 1.05044371078583e-08
Según los resultamos numéricos, nuevamente convergió bien el método.
NOTA: Para los siguientes métodos heurísticos que se basan en poblaciones e iteraciones, estos parámetros serán iguales para todos; 50 miembros y 100 iteraciones.
Los algoritmos evolutivos (AE) son métodos de optimización inspirados
en los mecanismos de la evolución biológica. Funcionan con una población
de posibles soluciones que evolucionan a lo largo de varias
generaciones mediante operaciones como la selección, cruzamiento,
mutación y elitismo. La función ga
de la librería
GA
la implementa y cuenta con parámetros como:
El objetivo es encontrar una solución óptima o cercana al óptimo para un problema, especialmente cuando los métodos tradicionales no son eficaces debido a la complejidad del espacio de búsqueda.
Para la implementación en código R de GA
se tomó como
guía la documentación dispuesta en ‘Scrucca, L. (2025). GA:
Genetic Algorithms. CRAN’.
Comenzamos con el caso 1D.
## Mejor solución encontrada:
## x = 0
## Con un valor óptimo de 0 en 100 iteraciones
Fig.9 GA Rastrigin 1D
Vemos que no supone mayor dificultad para el método hallar una solución exacta en baja dimensionalidad.
Procedemos con la de Rastrigin 2D, considerando diversos argumentos de la función.
## Mejor solución encontrada:
## (x, y) = (0, 0)
## Con un valor óptimo de 0 en 100 iteraciones
Fig.10 GA Rastrigin 2D
Nuevamente, la solución hallada es exacta para este caso de 2 dimensiones de entrada.
Veamos que tal con la versión 3D.
## Mejor solución encontrada:
## (x, y, z) = (0, 0, 0)
## Con un valor óptimo de 0 en 100 iteraciones
De nuevo, solución perfectamente exacta.
Es momento de evaluar ahora que tal le va al método con la de Rosenbrock, si logrará la misma exactitud que con Rastrigin. Comenzado de nuevo entonces con el caso 1D.
## Mejor solución encontrada:
## x = 0.999999501247124
## Con un valor óptimo de -9.97504772334171e-11 en 100 iteraciones
Fig.11 GA Rosenbrock 1D
Se obtiene una solución que a términos prácticos es exacta.
Luego, para el caso 2D de Rosenbrock.
## Mejor solución encontrada:
## (x, y) = (0.999821444661359, 0.9996430029726)
## Con un valor óptimo de -3.18826775556571e-08 en 100 iteraciones
Fig.12 GA Rosenbrock 2D
Continua siendo muy buena la solución sin problema alguno.
Ahora el de Rosenbrock 3D.
## Mejor solución encontrada:
## (x, y, z) = (0.999902313108414, 0.999805319634613, 0.999610896342258)
## Con un valor óptimo de -4.74947456265742e-08 en 100 iteraciones
Según los resultados númericos, se aproxima bastante bien.
Se basa en las ideas de comportamientos de poblaciones como grupos de
aves, que en búsqueda de alimento, no solo se mueven a cierta velocidad,
sino que buscan en base a lo que observan del entorno, y lo que observan
en sus compañeros. Para aplicar la optimización por enjambre de
partículas se empleó la función psoptim
de la librería
pso
(particle swarm optimization). Esta permite modificar
diversos parámetros como por ejemplo:
Entre muchos otros parámetros adicionales, pero, para este caso particular de comparación de métodos de optimización, solo se modificará el máximo número de iteraciones y población, los demás parámetros se dejarán por defecto.
Para la implementación en código R de PSO
se tomó como
guía la documentación dispuesta en ‘Clerc, M., & Coelho, L. S.
(2022, Octubre 14). pso: Particle Swarm Optimization (Version 1.0-5)
[Manual de referencia]. The R Project for Statistical
Computing.’.
## La mejor solución hallada es:
## x = 1.73824685829077e-05, con f(x) = 6.00024101515828e-08.
## Usando 100 iteraciones.
Fig.13 PSO Rastrigin 1D
La solucion númerica se aproxima lo suficientemente bien para ser gráficamente perfecta.
Vemos ahora para el caso 2D a 3D.
## La mejor solución hallada es:
## x = 1.73824685829077e-05, y = 5.41619145005576e-07, con f(x,y) = 6.00024101515828e-08.
## Usando 100 iteraciones.
Veamos en una gráfica de curvas de nivel la solución hallada:
Fig.14 PSO Rastrigin 2D
Continuamos con una solución óptima del método, suficientemente buena gráficamente, con un error despreciable.
Finalizamos Rastrigin con PSO mirando el caso 3D.
## La mejor solución hallada es:
## x = 0.00795172284832642, y = -0.000250197075416108, con f(x,y) = 0.0126238210993428.
## Usando 100 iteraciones.
Se sigue aproximando decentemente, pero ya empieza a resultarle más complicado al método.
## La mejor solución hallada es:
## x = 0.00795172284832642, con f(x) = 0.0126238210993428.
## Usando 100 iteraciones.
Fig.15 PSO Rosenbrock 1D
No le cuesta mucho en 1D aproximarse bien, pero de primeras no logra el mismo nivel de exactitud numérico que los algoritmos evolutivos.
Ahora veamos el resultado de optimizar la de Rosenbrock 2 variables.
## La mejor solución hallada es:
## x = 1.00096511939299, y = 1.0018622281904, con f(x,y) = 1.40675608269388e-06.
## Usando 100 iteraciones.
Fig.16 PSO Rosenbrock 2D
Ahora veamos el resultado de optimizar la de Rosenbrock con variables x,y,z.
## La mejor solución hallada es:
## x = 0.898746387671411, y = 0.814071484869055, z = 0.66124977362888, con f(x,y,z) = 0.0490379825415431.
## Usando 100 iteraciones.
Vemos que ya en 3D el método de enjambre de partículas, le cuesta obtener resultados decentes con la función de Rosenbrock, se evidencia principalmente en la 3ra coordenada, con \(z\approx 0.6612\).
La evolución diferencial (DE) es un algoritmo evolutivo específico, que se diferencia por su metodología para generar variación entre individuos por medio de diferencias entre ellos, modulada por un factor de escala F, a parte de tener las otras operaciones de los algortimos evolutivos convencionales. Los parámetros principales de este algoritmo incluyen:
DE es adecuado para problemas con espacios de búsqueda no lineales y multidimensionales, y es menos propenso a quedar atrapado en óptimos locales en comparación con otros algoritmos de optimización.
El código en R para está subsección de DE
se desarrolló
según documentación Mullen, K., Ardia, D., Gil, D., Windover, D.,
& Cline, J. (2025). DEoptim: Global Optimization by Differential
Evolution. CRAN.
Iniciamos esta sub-sección con Rastrigin 1D.
## Valor óptimo Rastrigin 1D → f* = 1.04805053524615e-13.
## Obtenido en x = 2.2989377927243e-08.
## Usando 100 iteraciones.
Fig.17 DE Rastrigin 1D
Empieza bien, pero no precisamente con la mayor de las exactitudes de todos los métodos.
Proseguimos optimizando la función en 2D.
## Valor óptimo Rastrigin 2D → f* = 0.00154272911834141.
## Obtenido en (x,y) = (0.00172512919681201, 0.00219093500219472).
## Usando 100 iteraciones.
Evaluemos la calidad de la solución visualmente con una gráfica de
contornos de nivel.
Fig.18 DE Rastrigin 2D
Aquí ya se aprecia ligeramente mayor desviación en la solución hallada.
Veamos ahora como le va para el caso de tres variables de entrada.
## Valor óptimo Rastrigin 3D → f* = 0.191570036875426.
## Obtenido en (x,y,z) = (0.0223378538065587, 0.0214201641130212, 0.00305181153790221).
## Usando 100 iteraciones.
Como era de esperar, cada vez le resulta más costoso mejorar la solución en Rastrigin al aumentar la dimensionalidad.
Continuamos ahora con la optimización por evolución diferencial para la de Rosenbrock en 1D.
## Valor óptimo Rosenbrock 1D → f* = 3.34126966787017e-27.
## Obtenido en x = 1.
## Usando 100 iteraciones.
Fig.19 DE Rosenbrock 1D
Vemos que la evolución diferencial arranca teniendo un resultado exacto en el argumento que minimiza a la función de Rosenbrock.
Ahora bien, veamos si el buen desempeño se mantiene con una entrada 2D.
## Valor óptimo Rosenbrock 2D → f* = 9.87537269674006e-21.
## Obtenido en (x,y) = (1.00000000006936, 1.00000000014584).
## Usando 100 iteraciones.
Fig.20 DE Rosenbrock 2D
El método continua produciendo un muy buen resultado con esta función.
Veamos que tal con entrada 3D (x, y, z).
## Valor óptimo Rosenbrock 3D → f* = 2.00531391570777e-11.
## Obtenido en (x,y,z) = (0.99999829525011, 0.999996667066797, 0.999993567646815).
## Usando 100 iteraciones.
A términos generales, la evolución diferencial le va especialmente
bien con la función de Rosenbrock
Para poder generar los gifs, es necesario activar el monitoreo o trazabilidad de los miembros de las poblaciones, para cada iteración, por lo cual se volverán a correr todos los métodos de optmización pero con parámetros específicos.
Observación: Las celdas de producción de GIFs solo se ejecutaron una vez para generar los archivos, y ya luego se etiquetaron con HTML. Para la ejecución del .Rmd cambiar “eval = FALSE” a “eval = TRUE”, o en su defecto borrar ese parámetro del chunk.
Comenzamos produciendo el GIF para Rastrigin.
Se aprecia inmediatamente que el método convergió muy rápido,
pero a un mínimo local.
Miramos el GIF de Rosenbrock con gradiente.
Recordando que acorde al código, debido a la enorme cantidad de
iteraciones del método de gradiente, se tomaron iteraciones en pasos
grandes; se puede observar que aunque son muchas iteraciones, logra
alcanzar el mínimo global. Esto sumado a las ejecuciones iniciales de
experimentación, denota que la función de Rosenbrock, tiene una
topografía que no perjudica tanto al método, si lo comparamos con la de
Rastrigin por ejemplo.
NOTA: Para los GIF de los métodos heurísticos, se emplean 20 miembros de población y 100 iteraciones.
Para poder guardar los puntos de cada población en cada iteración con
la librería GA
fue necesario crear previamente una función
de monitoreo, y luego pasarla a los argumentos de la función
ga
.
Se aprecia que hay puntos que llegan al mínimo global, pero al
final de las iteraciones, varios miembros permanecieron en mínimos
locales, aquí la ventaja de obtener la buena solución es por el
almacenamiento de las coordenadas que dan el mejor valor detectado al
final del algoritmo.
Veamos ahora para Rosenbrock con GA.