INVURNUS En busca del conocimiento Volumen 6 No. 1 ( Enero-Junio 2011): 15-20 División de Ciencias e Ingeniería TECNOLOGÍA Planeación de Rutas de Distribución utilizando el Algoritmo Heurístico 2-Optimal: Implementación Computacional Gómez Quezada Mario 1*, León Moreno Francisco Javier 2 1 Profesor de carrera en el área de ingeniería. Departamento de Física Matemática e Ingeniería 2 Profesor de asignatura en el área de ingeniería. Resumen En un trabajo previo (León y Gómez, 2008) se analizó el algoritmo 2-Optimal demostrando ser un muy buen método para dar solución al problema del agente viajero (PAV). El objetivo de este trabajo es la implementación computacional del algoritmo heurístico 2- Optimal. Este método de aproximación es de tipo de mejoramiento, ya que parte de una solución factible inicial y su meta es encontrar un mejor recorrido al inicialmente propuesto. El prototipo computacional será desarrollado en Visual Basic orientado a objetos, los componentes de los algoritmos auxiliares, estarán conformados en clases incluyendo el algoritmo 2-Optimal, ésta implementación aportará una flexibilidad muy importante que podrá ser aprovechada en su aplicación a casos reales. El desarrollo de este trabajo, permitirá con mayor facilidad hacer adecuaciones para casos específicos, al realizar estudios más precisos sobre las ventajas del algoritmo en la aplicación a rutas de distribución de casos reales. Palabras Claves: PAV, Algoritmo, Vecino más cercano, 2-Optimal, prototipo computacional. Abstract Planning of Distribution Routes, Using the Heuristic 2-Optimal Algorithm: Computational Implementation In a previous study (León and Gómez, 2008) the 2-Optimal algorithm was analyzed and showed to be a very good method for solving traveling salesman problem (TSP). The objective of this work is the computational implementation of heuristic 2-Optimal algorithm. This approximation method is for improvement, as part of an initial feasible solution and its goal is to find a better route than initially proposed. The computational prototype will be developed in Visual Basic object-orientated; the components of the auxiliary algorithms will be formed into classes including 2-optimal algorithm. This implementation will provide an important flexibility that may be exploited in its application in to real cases. The development of this work will easily make adjustments for specific cases, to make precise studies about the advantages of the algorithm in the distribution route implementation for real cases. Keywords: TSP, algorithm, nearest neighbor, 2-Optimal, computational prototype. *Autor para envío de correspondencia: Ave. Universidad e Irigoyen s/n. Col, Ortiz, H. Caborca Sonora México. C.P. 83600. Teléfono/Fax: (637) 372-65-40. E-mail: mgomezq@caborca.uson.mx. 2011 Editorial UNISON URN. Derechos reservados.
16 Introducción El diseño de rutas para la distribución de productos o servicios es algo complejo, no tanto en términos de dificultad sino en tiempo de ejecución, esto se agrava cuando el número de puntos a visitar es numeroso, sobre todo cuando se aplica a casos reales, por lo que se requiere de alguna herramienta computacional para llegar a la solución. El algoritmo 2-Optimal ha demostrado ser un buen método para el cálculo de rutas de distribución, por lo que el objetivo de este trabajo, es la implementación computacional de este algoritmo, incluyendo algoritmos auxiliares necesarios para su implementación, tales como importar datos, grafo computacional y algoritmo del vecino más cercano. El trabajo culmina con un prototipo computacional implementado en Visual Basic orientado a objetos, esto le da flexibilidad para adecuarlo a futuras aplicaciones reales. El prototipo permite calcular paso a paso cada algoritmo, hasta llegar a la solución planteada por el algoritmo 2-Optimal, también permite calcular todo el proceso en forma automática. Materiales y Métodos En un trabajo previo (León y Gómez, 2008) se analizó el algoritmo 2-Optimal demostrando ser buen método para dar solución al problema del agente viajero (PAV) (Zbigniew Michalewicz, 2004), éste algoritmo debe iniciar con una solución inicial factible, por lo que se utilizó como solución inicial el algoritmo del vecino más cercano, posteriormente se aplicó el algoritmo 2-Optimal para mejorar la solución inicial. Para la aplicación del algoritmo 2-Optimal se realizaron los siguientes pasos: Paso 1. Iniciar con una ruta factible. En este caso la ruta inicial propuesta será la que resulte de aplicar el algoritmo del vecino más cercano. Paso 2. Seleccionar 2 aristas no adyacentes y proponer 2 nuevas aristas. De la ruta inicial propuesta se seleccionan un par de aristas no adyacentes (i k,j k ) y (i L,j L ) sumando sus pesos, luego se selecciona otro par de aristas (i k,i L ) y (j k,j L ) sumando sus pesos (k y L son los índices del orden de enrutamiento), se compara la suma de sus pesos y si la suma del segundo par de aristas, es menor, se procede a hacer el cambio de tal forma que se conforma otra nueva ruta, si no, se busca otro par. Este proceso se repite hasta no encontrar un par de aristas de menor peso (León y Gómez, 2008). La implementación computacional se desarrolló en Visual Basic orientado a objetos (Peter Wright, 1998), la fuente de datos (matriz de adyacencia) fue la hoja electrónica Excel. Los datos fueron importados (clsenlacebd) para conformar el grafo computacional (clsgrafocomp), una vez que la computadora es capaz de interpretar correctamente los nodos, aristas y pesos, se calculó el enrutamiento inicial a través del algoritmo del vecino más cercano (clsvecinocercano) y por último, ésta solución se utilizó como enrutamiento inicial en el algoritmo 2-Optimal (clsdosoptimal) con la finalidad de encontrar un mejor enrutamiento. Para importar los datos se aplicó la tecnología ADO/OLE DB, (Rob Bovey, Stephen Bullen, 2003) la cual utiliza la propiedad DataSource para enlazar dinámicamente el origen de datos. Se utilizó la hoja electrónica Excel por la facilidad de analizar varios ejemplos de matrices de adyacencia para probar la mejora del enrutamiento por el algoritmo 2-optimal, así como los resultados arrojados por el prototipo. Se implementaron los principales algoritmos en componentes de clase, con la finalidad de dar flexibilidad al prototipo de ajustarse a los requerimientos de problemas reales. Las variables y objetos globales se declararon en módulos con la finalidad de que puedan ser reconocidos en todo el proyecto. El prototipo fue desarrollado de tal manera que se puede dar seguimiento a las diferentes etapas del proceso, visualizando los resultados parciales a través del componente MSFlexGrid para Visual Basic, los diferentes pasos de cálculo se pueden seleccionar a través de un menú en la interfase gráfica principal (Figura 1). Figura 1. Interfase gráfica del prototipo computacional. Presentación de los datos. Como fuente de datos se utilizó la hoja electrónica de Excel, ya que permite organizarlos directamente en forma matricial. Uno de los ejemplos de datos que se usaron en este trabajo para Gómez Quezada y León Moreno, Implementación computacional para la planeación de rutas de distribución:.
INVURNUS, Vol. 6 No. 1 (2011): 15-20 17 el desarrollo de la implementación computacional, se muestran en la Figura 2a. a) b) Figura 2. a) Datos de prueba capturados en hoja de cálculo Excel, R i renglones, C j columnas. b) Datos importados de Excel (matriz de adyacencia). Importar datos. Los datos presentados en Excel deben ser importados para manipularse directamente con el lenguaje Visual Basic. El procedimiento para importar los datos se encuentra en (Gómez Quezada, 2004) donde se presenta el código en Visual Basic utilizando la tecnología ADO/OLE DB, la cual usa la propiedad DataSource para enlazar dinámicamente el origen de datos. Las clases que utilizaremos son: clsenlacebd, clscargarmatricesrs y clsestructura. Las clases anteriores serán referenciadas por los siguientes objetos: Public obenlacedatos As New clsenlacebd Public obcargarmatricesrs As New clscargarmatricesrs Public stmatriz As New clsestructura. Una vez que ya son creados los objetos anteriores, automáticamente se llama al método AbrirBD(StrConexion) utilizando el siguiente argumento: StrConexion = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\" & _ "EjemploDatos.xls" & ";Extended Properties=Excel 8.0;" El archivo de Excel con el que se realiza el enlace en este caso se llama EjemploDatos.xls, el cual contiene varias matrices de adyacencia con sus respectivos nombres de rangos, que se muestran en una lista desplegable para poder seleccionar el ejemplo que se quiera analizar. Una vez que se selecciona se ejecuta el método CargarMatrices de la clase obcargarmatricesrs, pasando la información a un objeto stmatriz de la clase clsestructura de la siguiente manera: stmatriz.fnmatriz() = obcargarmatricesrs.cargarmatrices(obenlacedat os, Form1.Combo1.Text) stmatriz.ren = obcargarmatricesrs.renglones stmatriz.col = obcargarmatricesrs.columnas Después de realizar lo anterior se visualiza la información como se muestra en la Figura 2b. Una vez que ya hemos realizado la importación de los datos, los cuales se encuentran en memoria, continuamos con su manipulación para darle seguimiento al proyecto. Representación computacional del grafo. Una vez obtenida la matriz de adyacencia se procede a construir la forma tabular del grafo al que llamaremos grafo computacional. Esta forma de representación de la matriz nos ayudará a darle seguimiento al algoritmo de manera más precisa para encontrar la solución, ya que el grafo computacional presenta el conjunto total de aristas que contiene el problema, el par de nodos conectados por cada arista y el peso correspondiente a cada una de ellas. El grafo computacional se calcula a través de la clase clsgrafocomp. Esta clase la utilizaremos a través del objeto obgrafo, el cual lo declararemos de la siguiente forma: Public obgrafo As New ClsGrafoComp La Figura 3a muestra las propiedades y métodos de la clase clsgrafocomp a través del objeto obgrafo. a) b) c) Figura 3. a) Propiedades y métodos de la clase clsgrafocomp. b) Propiedades y métodos de la clase clsvecinocercano. c) Propiedades y métodos de la clase clsdosoptimal. Del objeto obgrafo se ejecuta el método Obtener llamándolo con la siguiente instrucción: Call obgrafo.obtener(stmatriz). Una vez ejecutado este método obtenemos el grafo a través de la propiedad tipo matricial FnMatriz y sus dimensiones por medio de las propiedades Ren y Col. El grafo computacional lo almacenaremos en un objeto de tipo estructura stgrafo, el cual lo declararemos como una instancia de la clase clsestructura, con la siguiente instrucción: Public stgrafo As New clsestructura Una vez declarada la estructura stgrafo almacenamos la información del grafo. stgrafo.fnmatriz = obgrafo.fnmatriz stgrafo.ren = obgrafo.ren stgrafo.col = obgrafo.col Podemos visualizar en pantalla el grafo computacional por cualquier método, en este caso
18 utilizamos el componente de Visul Basic MSFlexGrid. La Figura 4 presenta el grafo computacional que se obtiene de la matriz de adyacencia del problema mostrado en la Figura 2b. strutavc.fnmatriz = obgrafo.fnmatriz strutavc.ren = obgrafo.ren strutavc.col = obgrafo.col Después de calcular la tabla de enrutamiento se podrá obtener la secuencia de nodos y visualizarlo en pantalla. La Figura 5 presenta la tabla de enrutamiento al aplicar el algoritmo del vecino más cercano a partir del grafo computacional mostrado en la Figura 4. Resultados y Discusión Figura 4. Grafo computacional El vecino más cercano. El algoritmo del vecino más cercano consiste básicamente en iniciar en un nodo concreto que sea el origen de partida, que en este caso es el nodo i =1, y seleccionar la arista que contenga el mínimo peso que nos lleve al siguiente nodo j, y así sucesivamente hasta llegar de nuevo al nodo origen (i =1). El algoritmo del vecino más cercano lo calcularemos a través de la clase clsvecinocercano. Esta clase la utilizaremos a través del objeto obruta, el cual lo declararemos de la siguiente forma: El resultado al ejecutar el algoritmo del vecino más cercano se almacenó en una tabla llamada tabla de enrutamiento, la cual es un subconjunto del grafo computacional. Esta tabla de enrutamiento presenta en la primera columna el orden en que se deben seleccionar las aristas para obtener la solución encontrada por el algoritmo, donde dicha solución es la suma de los pesos de las aristas correspondientes. De igual manera en la Figura 5, la columna etiquetada por la letra k presenta el orden que se debe seguir para la selección de aristas, las cuales son las que se encuentran en la columna X, sus nodos correspondientes se encuentran en las columnas i y j, y su peso respectivo se encuentra en la columna P. Public obruta As New clsvecinocercano. La Figura 3b muestra las propiedades y métodos de la clase clsvecinocercano a través del objeto obruta. Del objeto obruta se ejecuta el método ObtenerVC llamándolo con la siguiente instrucción: Call obruta.obtenervc(stgrafo, stmatriz.ren). Este método requiere de dos datos de entrada en su argumento. Uno de ellos es el objeto estructura del grafo, la cual ya se obtuvo y está contenida en objeto stgrafo. El otro dato de entrada son los renglones de la matriz, los cuales se encuentran en stmatriz.ren. Una vez ejecutado el método ObtenerVC se obtiene la tabla enrutamiento a través de la propiedad tipo función FnMatriz y sus dimensiones por medio de las propiedades Ren y Col. La ruta obtenida la almacenaremos en un objeto de tipo estructura strutavc, el cual lo declararemos como una instancia de la clase clsestructura, con la siguiente instrucción: Public strutavc As New clsestructura Una vez declarado almacenamos la información de la ruta obtenida por el algoritmo. Figura 5. Tabla de enrutamiento para la solución del algoritmo del vecino más cercano. Hasta este momento se ha encontrado una solución aplicando el algoritmo del vecino más cercano, pero como ya mencionamos anteriormente, se tomará como propuesta de solución inicial para el algoritmo 2- Optimal que describiremos en el siguiente punto. Algoritmo 2-Optimal. El algoritmo 2-Optimal dará la posibilidad de encontrar un mejor ciclo hamiltoniano (León y Gómez, 2008) en el cual la suma de sus pesos sea menor a la solución propuesta en el punto anterior por el algoritmo del vecino más cercano. El algoritmo 2- Optimal consta de los siguientes pasos: Gómez Quezada y León Moreno, Implementación computacional para la planeación de rutas de distribución:.
INVURNUS, Vol. 6 No. 1 (2011): 15-20 19 Paso 1. Iniciar con una ruta factible. En este caso se propone la ruta encontrada por el algoritmo del vecino más cercano que se presenta en la Figura 5. Paso 2. De la ruta inicial propuesta se seleccionan un par de aristas no adyacentes (i k,j k ) y (i L,j L ) sumando sus pesos, luego se selecciona otro par de aristas (i k,i L ) y (j k,j L ) sumando sus pesos (k y L son los índices del orden de enrutamiento). Paso 3. Calcular la diferencia de peso entre el par de aristas seleccionadas para eliminar y el par de aristas propuestas para reconectar. Si la diferencia de peso es mayor que cero (Delta>0) entonces se ha encontrado un mejor par de aristas, por lo que hay que reconectar este nuevo par de aristas para formar un nuevo ciclo hamiltoniano y se repite el proceso iniciando con el nodo 1. Si no, seleccionar otro conjunto de 2 aristas para intercambiarlas y calcular la diferencia de peso entre los pares de aristas. Tales intercambios de 2 aristas se continúan hasta que ninguna otra mejora se pueda, Delta=0 (León y Gómez, 2008). El cálculo del algoritmo 2-optimal lo calcularemos a través de la clase clsdosoptimal. Esta clase la utilizaremos a través del objeto obdosoptimal, el cual lo declararemos de la siguiente forma: Public obdosoptimal As New clsdosoptimal. La Figura 3c muestra las propiedades y métodos de la clase clsdosoptimal a través del objeto obdosoptimal. Del objeto obdosoptimal se ejecuta el método ObtenerDO llamándolo con la siguiente instrucción: Call obdosoptimal.obtenerdo(stgrafo, strutavc). Este método requiere de dos datos de entrada en su argumento. Una de ellos es la estructura del grafo, que se encuentra en el objeto stgrafo. El otro dato de entrada es la ruta inicial que fue calculada por el algoritmo del vecino más cercano que se encuentra en el objeto strutavc. Una vez ejecutado el método ObtenerDO se obtiene la tabla enrutamiento de la solución para el algoritmo 2-Optimal, a través de la propiedad tipo función FnMatriz y sus dimensiones por medio de las propiedades Ren y Col. La ruta obtenida la almacenaremos en un objeto de tipo estructura strutadoso, el cual lo declararemos como una instancia de la clase clsestructura, con la siguiente instrucción: Public strutadoso As New clsestructura Una vez declarado almacenamos la información de la ruta obtenida por el algoritmo. strutadoso.fnmatriz = obdosoptimal.fnmatriz strutadoso.ren = obdosoptimal.ren strutadoso.col = obdosoptimal.col Una vez que ya está calculada esta tabla de enrutamiento podemos obtener la secuencia de nodos y visualizarlo en pantalla. La Figura 6 presenta la tabla de enrutamiento, la secuencia de nodos y la suma de los pesos correspondientes para la solución encontrada por el algoritmo 2-Optimal. Figura 6. Tabla de enrutamiento para la solución encontrada por el algoritmo 2-Optimal. Recordemos que el algoritmo 2-Optimal es de tipo de mejoramiento que parte de una solución factible inicial. Si se compara la Figura 5 con la Figura 6, vemos que efectivamente se obtuvo una mejora, ya que la suma de pesos es de 1546 para la solución encontrada por el algoritmo del vecino más cercano, y de 1352 para el algoritmo 2-Optimal. Hasta este momento se ha logrado modelar computacionalmente el algoritmo 2-Optimal para obtener un ciclo hamiltoniano cercano al óptimo para cualquier matriz de adyacencia. El prototipo contempla la posibilidad de calcular cada uno de los algoritmos en forma independiente (paso a paso) hasta llegar a la solución con el algoritmo 2-Optimal o calcular automáticamente todos los algoritmos llegando a la misma solución. El prototipo puede ser aplicado en forma general para cualquier caso que cumpla con las condiciones establecidas por el propio algoritmo así como las del PAV. Conclusiones El trabajo consistió en diseñar un prototipo que se aplica de manera general para cualquier problema del tipo PAV simétrico. Con la implementación computacional del algoritmo 2-Optimal, se logró contar con una herramienta computacional que proporciona una muy buena solución al PAV, permitiendo seguir analizando su comportamiento para diferentes problemas de enrutamiento, sobre todo problemas con un número considerable de puntos a visitar.
20 En el ejemplo mostrado en este trabajo se puede observar una mejora importante de este algoritmo con respecto al enrutamiento inicial. Considerando el establecimiento de ciertas condiciones, el prototipo completo cumple el objetivo de servir como apoyo para la toma de decisiones en la planeación de rutas de Bibliografía Craig Larman, 2007. Introducción al análisis y diseño orientado a objetos, Prentice Hall. Libro. Gómez Quezada, 2004. Análisis e implementación de un algoritmo de asignación para el diseño de horarios en Instituciones de Educación Superior. Instituto Tecnológico de Nogales. Tesis, 65-71. Hillier y Lieberman, 2002. Investigación de Operaciones. Séptima Edición. Mc-Graw-Hill. Libro. León y Gómez, 2008. Planeación de rutas de distribución utilizando el algoritmo 2-Optimal. Invurnus volumen 3 número2. Universidad de Sonora. 16-26. Pedro Larrañaga y Iñaki Inza, 2004. Heurísticos en optimización combinatoria. Departamento de Ciencias de la Computación e Inteligencia Artificial. Universidad del País Vasco. Libro. distribución, ya que contempla el cálculo de la ruta óptima para diferentes escenarios, además, tomando en cuenta su implementación en módulos de clase permite adecuarlo a los requerimientos de distribución de productos de cualquier organización. Peter Wright, 1998. Begining Visual Basic 6 Objects, Published by Wrox Press. Primera edición, Libro, 235-263. Prawda, 1976. Métodos y Modelos de Investigación de Operaciones, vol. 1 Modelos Determinísticos Ed. Limusa. Libro, 559-565. Rafael Martí, 2009. Algoritmos heurísticos en optimización combinatoria. Departamento de Estadística e Investigación Operativa. Universidad de Valencia. Libro. Rob Bovey and Stephen Bullen, 2003. Excel 2002 VBA Programmer s Reference, Wrox, 411-415. Zbigniew Michalewicz y David B. Fogel, 2004. How to solve It: Modern Heuristics, Second Edition, 61-68. Gómez Quezada y León Moreno, Implementación computacional para la planeación de rutas de distribución:.