#+TITLE: Práctica 3 #+SUBTITLE: Metaheurísticas #+AUTHOR: Amin Kasrou Aouam #+DATE: 2021-06-22 #+PANDOC_OPTIONS: template:~/.pandoc/templates/eisvogel.latex #+PANDOC_OPTIONS: listings:t #+PANDOC_OPTIONS: toc:t #+PANDOC_METADATA: lang=es #+PANDOC_METADATA: titlepage:t #+PANDOC_METADATA: listings-no-page-break:t #+PANDOC_METADATA: toc-own-page:t #+PANDOC_METADATA: table-use-row-colors:t #+PANDOC_METADATA: colorlinks:t #+PANDOC_METADATA: logo:/home/coolneng/Photos/Logos/UGR.png #+LaTeX_HEADER: \usepackage[ruled, lined, linesnumbered, commentsnumbered, longend]{algorithm2e} * Práctica 3 ** Introducción En esta práctica, usaremos distintos algoritmos de búsqueda, basados en trayectorias, para resolver el problema de la máxima diversidad (MDP). Implementaremos: - Enfriamiento simulado - Búsqueda multiarranque ** Algoritmos *** Enfriamiento simulado El enfriamiento simulado es un algoritmo de búsqueda basado en trayectorias, con un criterio probabilístico basado en la termodinámica. El procedimiento general del algoritmo queda ilustrado a continuación: \begin{algorithm} \KwIn{A list $[a_i]$, $i=1, 2, \cdots, n$, that contains the components of a solution} \KwOut{Processed list} $currentSol \leftarrow initialize()$ $T0 \leftarrow initialize()$ $Tf \leftarrow initialize()$ $bestSol \leftarrow currentSol$ $T \leftarrow Tf$ \While{$T > Tf$}{ $neighbour \leftarrow generateNeighbour(currentSol)$ $delta \leftarrow fitness(neighbour) - fitness(currentSol)$ \If{$delta > 0 \vee acceptNeighbour(neighbour)$}{ $currentSol \leftarrow neighbour$ \If{$fitness(currentSol) > fitness(bestSol)$}{ $bestSol \leftarrow currentSol$ } } $coolDown(T)$ } \KwRet{$bestSolution$} \end{algorithm} *** Búsqueda multiarranque La búsqueda multiarranque es un algoritmo que itera las 2 etapas siguientes: 1. Generación de una solución inicial 2. Búsqueda local Es una variante simple de implementar a partir de una búsqueda local El procedimiento general del algoritmo queda ilustrado a continuación: \begin{algorithm} \KwIn{A list $[a_i]$, $i=1, 2, \cdots, m$, the solution} \KwOut{Processed list} $Solutions = [\ ]$ $initialSolutions \leftarrow getRandomSolutions()$ $Solutions.append(firstSolution)$ $maxIterations \leftarrow 1000$ \For{$i \leftarrow 0$ \KwTo $maxIterations$}{ \For{$element in initialSolutions$}{ $lastSolution \leftarrow getLastElement(initialSolutions)$ \While{$neighbour \leq lastSolution$}{ $neighbour \leftarrow getNeighbouringSolution(lastSolution)$ $Solutions.append(neighbour)$ $lastSolution \leftarrow getLastElement(neighbour)$ } $finalSolution \leftarrow getLastElement(Solutions)$ } } \KwRet{$finalSolution$} \end{algorithm} ** Implementación La práctica ha sido implementada en /Python/, usando las siguientes bibliotecas: - NumPy - Pandas \clearpage *** Instalación Para ejecutar el programa es preciso instalar Python, junto con las bibliotecas *Pandas* y *NumPy*. Se proporciona el archivo shell.nix para facilitar la instalación de las dependencias, con el gestor de paquetes [[https://nixos.org/][Nix]]. Tras instalar la herramienta Nix, únicamente habría que ejecutar el siguiente comando en la raíz del proyecto: #+begin_src shell nix-shell #+end_src ** Ejecución La ejecución del programa se realiza mediante el siguiente comando: #+begin_src shell python src/main.py #+end_src Los parámetros posibles son: | dataset | algoritmo | | Cualquier archivo de la carpeta data | annealing | | | multistart | También se proporciona un script que ejecuta 1 iteración de cada algoritmo, sobre cada uno de los /datasets/, y guarda los resultados en una hoja de cálculo. Se puede ejecutar mediante el siguiente comando: #+begin_src shell python src/execution.py #+end_src *Nota*: se precisa instalar la biblioteca [[https://xlsxwriter.readthedocs.io/][XlsxWriter]] para la exportación de los resultados a un archivo Excel. * Análisis de los resultados ** Enfriamiento simulado #+CAPTION: Enfriamiento simulado [[./assets/annealing.png]] El tiempo de ejecución varía ligeramente según el dataset: - Dataset con n=500: 13 segundos - Dataset con n=2000: 38-39 segundos La distancia total obtenida, toma valores muy diferentes según el dataset en el que se ejecuta. ** Búsqueda multiarranque Desafortunadamente, un /bug/ en el script de ejecución ha hecho que la segunda pestaña de la hoja de cálculo únicamente tenga el valor de los datasets.