scieee AI-readable full text Open interactive document viewer

Aplicación del modelo de transporte para optimizar el aprovisionamiento de supermercados a nivel provincial y regional

Pita Manzanares, Carlos

Abstract

El protagonismo que está tomando la logística en la actualidad nace del acercamiento de la red comercial al usuario final. La competencia obliga a las grandes superficies a disminuir costes, y el de transporte es uno de ellos. En este trabajo se pretende aplicar el modelo de optimización conocido como problema de transporte para minimizar el coste total de Mercadona en abastecer a sus supermercados. Se profundizará en el marco teórico del modelo matemático y se propondrá, haciendo uso de este, una solución para transportar de los centros logísticos a los supermercados de la provincia de Sevilla y de Andalucía, variando la elección de los costes. Ante la problemática de los excesos de demanda respecto a la oferta de los bloques logísticos, se pretende determinar los supermercados que quedarán desatendidos, las consecuencias y soluciones. En este trabajo se resuelven dos casos, los cuales requieren del uso de dos herramientas distintas. En primer lugar, se utiliza el Solver de Excel para determinar la estrategia óptima de envíos en la provincia de Sevilla. En segundo lugar, y debido al mayor número de variables y restricciones del modelo, se utiliza la colección de paquetes Pyomo en Python para resolver el caso de la comunidad autónoma de Andalucía. En ambos casos, se demuestra que los resultados obtenidos reducen al máximo los costes de transporte, y siendo estos coherentes.

Full text

i Equation Chapter 1 Section 1 Trabajo Fin de Grado Ingeniería de las Tecnologías Industriales Aplicación del modelo de transporte para optimizar el aprovisionamiento de supermercados a nivel provincial y regional Autor: Carlos Pita Manzanares Tutor: Alicia Robles Velasco Dpto. de Organización Industrial y Gestión de Empresas II Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2022 ii iii Trabajo Fin de Grado Ingeniería de Tecnologías Industriales Aplicación del modelo de transporte para optimizar el aprovisionamiento de supermercados a nivel provincial y regional Autor: Carlos Pita Manzanares Tutor: Alicia Robles Velasco Profesor Colaborador Dpto. de Organización Industrial y Gestión de Empresas II Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2022 iv v Proyecto Fin de Carrera: Aplicación del modelo de transporte para optimizar el aprovisionamiento de supermercados a nivel provincial y regional Autor: Carlos Pita Manzanares Tutor: Alicia Robles Velasco El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario: Acuerdan otorgarle la calificación de: Sevilla, 2022 El Secretario del Tribunal vi vii A mi familia A mis amigos A mis maestros viii ix Agradecimientos A mi madre por ser la razón por la que empecé y acabé esta carrera, cada aprobado conseguido tiene su sello. A mis amigos de la escuela, por ser el motor para continuar cada día y hacer bonitas las tardes en el fondo de la biblioteca. A mi tutora Alicia Robles por su apoyo y guía para conseguir los objetivos marcados. A Alex, por su ayuda inestimable en el proyecto. Carlos Pita Manzanares Sevilla, 2022 xvi 4.2.1 Pyomo 21 4.2.2 Pandas 21 4.2.3 Geopy 22 5. Implementación y resultados 23 5.1 Abastecimiento a nivel provincial (Sevilla). 23 5.1.1 Problema equilibrado 23 5.1.1.1 Kilómetros en línea recta como coste 23 5.1.1.2 Kilómetros en carretera como coste 29 5.1.2 Problema con exceso de producción 35 5.1.3 Exceso de demanda 42 5.2 Abastecimiento a nivel regional. 52 5.2.1 Problema equilibrado 59 5.2.2 Exceso de producción 73 5.2.3 Exceso de demanda 77 6. Conclusiones 85 Referencias 87 Anexo. Códigos de Python 89 Programa 1. Cálculo de distancias geodésicas entre centros logísticos supermercados. 89 Programa 2. Resolución del problema de transporte para el caso regional. 90 Programa 3. Creación de grafos con coordenadas UTM 94 xvii xviii Índice de tablas Tabla 1. Tabla de costes del problema de transporte. Fuente: Elaboración propia .......... 8 Tabla 2. Tabla de flujos del problema de transporte. Fuente: Elaboración propia ........... 9 Tabla 3. Problema de transporte. Fuente:Elaboración propia ........................................ 10 Tabla 4. Distancia entre centros logísticos y supermercados de municipios. Fuente: Elaboración propia .......................................................................................................... 18 Tabla 5. Tabla de flujos antes de ser rellenada por el Solver. Fuente: Elaboración propia ........................................................................................................................................ 19 Tabla 6:Centros logísticos, superficie y oferta. Fuente: Elaboración propia .................. 23 Tabla 7. Supermercados por municipio de la provincia. Fuente: Elaboración propia .... 24 Tabla 8. Distancia en línea recta entre centros logísticos y supermercados de la provincia. Fuente: Elaboración propia ............................................................................................. 25 Tabla 9. Solución de problema de transporte con la distribución de camiones a cada supermercado. Fuente: Elaboración propia. ................................................................... 27 Tabla 10. Tabla resumen caso provincial km línea recta. Fuente: Elaboración propia .. 28 Tabla 11. Distancia en carretera entre centros logísticos y supermercados de la provincia. Fuente: Elaboración propia ............................................................................................. 29 Tabla 12.Solución de problema de transporte con la distribución de camiones a cada supermercado. Fuente: Elaboración propia. ................................................................... 30 Tabla 13. Tabla resumen caso provincial km en carretera. Fuente: Elaboración propia 35 Tabla 14. Tabla de nodos origen para exceso de producción. Fuente: Elaboración propia ........................................................................................................................................ 35 Tabla 15.Solución de problema de transporte. Exceso producción. Fuente: Elaboración propia. ............................................................................................................................. 37 Tabla 16. Comparación problema equilibrado y sobreproducción. Fuente: Elaboración propia .............................................................................................................................. 38 Tabla 17. Tabla de nodos origen para exceso de demanda. Fuente: Elaboración propia 42 Tabla 18.Solución de problema de transporte. Exceso de demanda. Fuente: Elaboración propia .............................................................................................................................. 44 Tabla 19. Comparación demanda y abastecido. Fuente: Elaboración propia ................. 48 Tabla 20. Corrección al problema de exceso de demanda. Fuente: Elaboración propia 51 Tabla 21. Supermercados por municipio de Andalucía. Fuente: (Mercadona, 2021) .... 52 Tabla 22. Distancia entre supermercados y centros logísticos de Andalucía. Fuente: (Elaboración propia). ...................................................................................................... 55 Tabla 23. Capacidad de los centros logísticos para el caso regional. Fuente: Elaboración propia .............................................................................................................................. 59 Tabla 24. Camiones abastecidos desde el centro de Antequera. Fuente: Elaboración propia .............................................................................................................................. 62 xix Tabla 25. Camiones abastecidos desde el centro de Guadix. Fuente: Elaboración propia ........................................................................................................................................ 63 Tabla 26. Camiones abastecidos desde el centro de Huévar. Fuente: Elaboración propia ........................................................................................................................................ 64 Tabla 27.Tabla resumen caso regional y equilibrado. Fuente: Elaboración propia ....... 72 Tabla 28. Capacidad de los centros logísticos. Caso regional con exceso de producción. Fuente: Elaboración propia ............................................................................................. 73 Tabla 29.Camiones abastecidos desde el centro de Antequera Exceso Producción. Fuente: Elaboración propia .......................................................................................................... 74 Tabla 30. Camiones abastecidos desde el centro de Guadix Exceso Producción. Fuente: Elaboración propia .......................................................................................................... 75 Tabla 31. Camiones abastecidos desde el centro de Huévar. Exceso Producción. Fuente: Elaboración propia .......................................................................................................... 76 Tabla 32. Análisis exceso de producción. Fuente: Elaboración propia .......................... 77 Tabla 33. Tabla resumen caso regional y exceso de producción. Fuente: Elaboración propia .............................................................................................................................. 77 Tabla 34. Capacidad de los centros logísticos. Caso regional con exceso de demanda. Fuente: Elaboración propia ............................................................................................. 78 Tabla 35. Camiones abastecidos desde el centro de Antequera. Exceso demanda. Fuente: Elaboración propia .......................................................................................................... 78 Tabla 36. Camiones abastecidos desde el centro de Guadix. Exceso demanda. Fuente: Elaboración propia .......................................................................................................... 79 Tabla 37.Camiones abastecidos desde el centro de Huévar. Exceso demanda. Fuente: Elaboración propia .......................................................................................................... 80 Tabla 38. Supermercados sin abastecer. Caso regional. Fuente: Elaboración propia. ... 81 xx xxi Índice de figuras Figura 1.Cuota de mercado cadena de supermercados 2021. Fuente: (Orús, 2022) ........ 2 Figura 2. Esquema de la Estrategia del 8. Fuente: (Palau, 2020) ..................................... 3 Figura 3.Representación gráfica del problema de transporte. Fuente: Elaboración propia .......................................................................................................................................... 7 Figura 4. Esquema del algoritmo Branch & Bound. Fuente:(Shokrhy & Tanaka, 2018) ........................................................................................................................................ 11 Figura 5. Mapa con lo centros logísticos de Mercadona. Fuente:(Brines, 2018) ........... 14 Figura 6. Centro logístico de Huévar. Fuente: (Mercadona, 2018) ................................ 15 Figura 7. Interior del centro logístico de Guadix. (Mercadona,2013) ............................ 15 Figura 8. Interfaz del Solver antes de ser ejecutado. Fuente: Elaboración propia ......... 20 Figura 9. Distancia geodésica. Fuente:(Pandey, s.f.) ...................................................... 22 Figura 10. Grafo de abastecimiento del centro de Antequera. Caso Provincial y Equilibrado ..................................................................................................................... 32 Figura 11. Grafo de abastecimiento del centro de Huévar. Caso Provincial y Equilibrado ........................................................................................................................................ 33 Figura 12. Superposición de grafos de las Figuras 10 y 11 ............................................ 34 Figura 13.Interfaz del Solver antes de ser ejecutado para problema exceso de producción. Fuente: Elaboración propia ......................................................................... 36 Figura 14. Grafo de abastecimiento del centro de Antequera. Caso Provincial y Exceso de Producción ................................................................................................................. 39 Figura 15. Grafo de abastecimiento del centro de Huévar. Caso Provincial y Exceso de Producción. ..................................................................................................................... 40 Figura 16. Grafos de las figuras 15 y 14 superpuestos ................................................... 41 Figura 17. Interfaz del Solver antes de ser ejecutado para problema exceso de demanda. Fuente: Elaboración propia ............................................................................................. 43 Figura 18. Grafo de abastecimiento del centro de Antequera. Caso Provincial y Exceso de Demanda. ................................................................................................................... 45 Figura 19. Grafo de abastecimiento del centro de Huévar. Caso Provincial y Exceso de Demanda ......................................................................................................................... 46 Figura 20. Grafos de la figura 19 y 18 superpuestos ...................................................... 47 Figura 21. Distribución de supermercados sin abastecer. Fuente: Google Maps ........... 49 Figura 22. Coordenadas en fichero Excel. Fuente: Elaboración propia ......................... 55 Figura 23. Abastecimiento del centro de Antequera para el caso regional y equilibrado. ........................................................................................................................................ 66 Figura 24. Abastecimiento del centro de Huévar para el caso regional y equilibrado. .. 67 xxii Figura 25. Zoom de la figura 24 ..................................................................................... 68 Figura 26. Abastecimiento desde Guadix. Caso Regional y equilibrado ....................... 69 Figura 27. Zoom Figura 26 ............................................................................................. 70 Figura 28. Mapa de la provincia de Granada. Fuente: (Ideal Granada, 2017) ............... 82 Figura 29. Localización de los supermercados sin abastecer. Fuente: Elaboración propia ........................................................................................................................................ 82 Figura 30. Propuesta de ubicación de nuevo centro logístico. Fuente: Elaboración propia ........................................................................................................................................ 83 Figura 31. Localización centro San Isidro respecto a localidades en Almería. Fuente: Elaboración propia .......................................................................................................... 84 xxiii xxiv 1 1. INTRODUCCIÓN El transporte es uno de los pilares fundamentales en el campo de la logística. Su coste es, en definitiva, el que más impacto genera y sobre el que recae mayor importancia a la hora de optimizar procesos en este ámbito. Tanto las grandes multinacionales como las pequeñas empresas tratan de reducir los costes de transporte de diferentes maneras. En (Or, 2020) y (Melero, 2020) se detallan algunas de ellas: • Analizando y decidiendo como colocar la mercancía en los medios de transporte (camiones, furgonetas, trenes…) para optimizar el espacio. Los palés han supuesto un avance muy importante en el campo de la logística. Estos vienen estandarizados con medidas pensadas y adaptadas para el transporte en camiones para transportar la mayor cantidad de mercancía, lo cual permite reducir el tamaño de la flota y disminuir el número de viajes. • Calculando cual es la mejor ruta, no solo en función de la distancia, si no de las vías (carretera convencional, autopista, autovía..), del tráfico y peajes. Los planificadores en los centros logísticos deben decidir la estrategia más beneficiosa de distribución. • Definiendo planes de contingencia para afrontar los reveses inesperados en el proceso de transporte, como puede ser definir rutas alternativas en caso de cortes de carretera. • Monitoreando la carga y colocando “checkpoints” en cada etapa del proceso para evitar no solo perdidas de material, si no también discrepancias entre los receptores del material y los transportistas. • Implantando estrategias de mantenimiento preventivo en los vehículos. Tener los camiones a punto evitará problemas mecánicos que ralenticen todo el proceso. Existen 3 vías principales en el transporte de mercancías: marítima, aérea y terrestre. En esta última también podemos diferenciar entre el transporte ferroviario y el transporte por carretera. Cada una de estas vías tiene sus ventajas e inconvenientes y la decisión de usarlas en mayor o menor medida depende no solo de la distancia, sino de la infraestructura de transporte que dispongan las regiones a suministrar. Por ejemplo, el transporte de mercancías en tren es más barato por kilo transportado, pero requiere de una extensa red ferroviaria. En contraparte, el transporte por carretera es más caro por kilo transportado, pero ofrece la versatilidad y flexibilidad que da moverse en carreteras. El transporte marítimo, por otro lado, está más enfocado al comercio internacional. En este documento se desarrollará un análisis y estudio para optimizar las rutas de transporte entre los centros logísticos y los supermercados a nivel provincial y regional de la cadena Mercadona. La empresa valenciana, fundada en 1977 y bajo el mando de la familia Roig, se ha establecido como la líder en el sector nacional del retail. 8 2.4.1 Tabla de costes En las filas se sitúan los nodos de origen :! y en las columnas los nodos de destino ;" , que tendrán asignada una oferta %% y una demanda (& respectivamente, de tal forma que cada casilla (i,j) se asocie a la variable #!" , es decir, el coste de transportar el material de :! a ;" . Son siempre datos del problema. Tabla 1. Tabla de costes del problema de transporte. Fuente: Elaboración propia !! !" !# … !$ Oferta "! !!! !!" !!# … !!$ "! "" !"! !"" !"# … !"$ "" "# !#! !#" !## … !#$ "# … … … … … … … "% !%! !%" !%# … !%$ "% Demanda #! #" ## … #$ … 9 2.4.2 Tabla de flujos Esta tabla tiene las mismas dimensiones que la de costes. Contiene las variables del problema. Las filas seguirán siendo los orígenes y las columnas, los destinos. La variable !!" será la cantidad transportada del nodo origen :! al nodo destino ;" . Tabla 2. Tabla de flujos del problema de transporte. Fuente: Elaboración propia !! !" !# … !$ Oferta "! $!! $!" $!# … $!$ "! "" $"! $"" $"# … !"$ "" "# $#! $#" $## … $#$ "# … … … … … … … "% $%! $%" $%# … $%$ "% Demanda #! #" ## … #$ … Esta tabla permite identificar rápidamente si el problema está equilibrado. La suma de las ofertas de los nodos origen ∑ %!! debe coincidir con la suma de las demandas ∑ ("" de los nodos destino. 2.5 Métodos de resolución. Algoritmo simplex En (Muñuzuri, Onieva, Cortés, Guadix, & Ibañez, 2010) se describe el algoritmo a seguir para solucionar el problema mediante el método simplex. Para iniciar este método, se debe obtener una solución básica inicial. Uno de los métodos para hallarla es el método de la esquina noroeste. El algoritmo a seguir viene descrito detalladamente en (OpenCourseWare , s.f.). Partiendo de la tabla de transporte 10 Tabla 3. Problema de transporte. Fuente:Elaboración propia ;'# ;( ;) … ;* Oferta :'# !'' !'( !') … !'* %' :(# !(' !(( !() … !(* %( :)# !)' !)( !)) … !)* %) … … … … … … … :+# !+' !+( !+) … !+* %+ Demanda (' (( () … (* Elegimos la esquina noroeste de la tabla, es decir, la casilla !'' y asignamos el mayor flujo posible. Es decir, o toda la oferta correspondiente a ese origen /' o toda la demanda del destino ;'# . Para que se cumplan las restricciones, elegiremos el mínimo entre estos dos. Por lo tanto, la expresión formal para esta asignación sería !!" =min @ /!,A" B. Se pueden dar tres casos: - En el caso en el que el mínimo sea /! significará que hemos agotado la oferta de :!# (origen i), es decir, ese origen no tiene mas productos para ser transportados. Por ello, :!# se actualizaría a 0 y se elimina la fila i. La nueva demanda pasaría a ser A" - /! . - Si A" es el mínimo, significaría que hemos satisfecho la demanda A" . Por lo tanto, la demanda ;"# pasaría a ser 0 y se eliminaría la fila j. La nueva oferta pasaría a ser /! - A" . - En el caso en el que A" = /! , la oferta y la demanda se actualizan a 0 al mismo tiempo. Por lo tanto, se eliminan tanto la columna i como la j Tras esta primera asignación, volvemos a repetir el algoritmo. En el caso en el que solo quede una fila o columna, se asignan todas las unidades que estén sin asignar. Cabe destacar de este método que no tiene en cuenta los costes de transporte, lo que no lo hace muy interesante. Otro método de obtención de solución básica inicial a tener en cuenta es el de Vogel. Es muy similar al de la esquina noroeste, pero este si tiene en cuenta los costes a lo largo del algoritmo. Una vez se ha definido una solución admisible de partida, el algoritmo Simplex trata de encontrar nuevas soluciones que tengan un menor coste que la solución actual. Para ello, se recurre a las variables del dual asociadas a las restricciones del modelo original, o modelo primal. El algoritmo Simplex es un método iterativo que siempre encuentra el óptimo de modelos de programación lineal. Realizada la formulación asociada al problema de transporte, habrá que calcular los valores indicadores asociados a las variables no básicas para determinar si la solución básica inicial puede mejorar o no. El valor de estos indicadores y sus signos reflejarán si la variable no básica debe enterar en la base. El algoritmo completo se explica con detalle en (OpenCourseWare , s.f.). 11 2.6 Branch and Bound El algoritmo de Branch and Bound, que en español se traduce como Ramificación y poda, es un método de optimización. De (Guerequeta & Vallecillo, 1998), donde se hace un profundo análisis del algoritmo y sus aplicaciones, podemos extraer sus características principales. Cabe destacar que es una variante del Backtracking o la técnica de vuelta atrás, que viene igualmente detallada en el capítulo 6 del texto referido. Branch and Bound se basa en la generación de un árbol decisión como el de la Figura 4, creando descendientes de una manera sistemática. De cada nodo ramifican posibles soluciones posteriores a la actual. La característica principal del algoritmo es que detecta cuando la ramificación escogida deja de ser óptima, por lo que descarta o “poda”. Figura 4. Esquema del algoritmo Branch & Bound. Fuente:(Shokrhy & Tanaka, 2018) Se denomina nodos vivos aquellos con posibilidad de ser ramificados. Se deben almacenar en una estructura para que puedan ser recorridos durante la estrategia de búsqueda y se hará de manera distinta dependiendo de la estrategia de búsqueda. Para un problema de transporte, al incluir la particularidad de tener costes #!"# existe una estrategia que prioriza la existencia de estos y utiliza una función de costes para el proceso de ramificación. Por lo tanto, y resumiendo el texto referenciado anteriormente, primero se debe seleccionar uno de los nodos vivos según la estrategia seguida. Una vez escogido, se ramifica, es decir, se expande el nodo con los posibles nodos hijos del seleccionado. Finalmente, se poda algunos de los nodos creados al expandirse el escogido inicialmente (también dependiendo del criterio escogido) y los no podados vuelven a la estructura de nodos vivos. La razón por la que se ahonda en este algoritmo es que es el que utiliza internamente el solver GPLK. Este utiliza el método simplex revisado y el método de punto interior primal-dual para problemas no enteros y el algoritmo de Branch and Bound junto con cortes enteros mixtos de Gomory para problemas enteros (mixtos). 2.7 El problema de asignación Es una extensión o caso particular del problema de transporte. El objetivo es asignar recursos a tareas minimizando el coste de la operación. La importancia del problema radica en que cada recurso solo se puede asignar a una tarea y cada tarea solo puede ser asignada por una tarea. Las variables de decisión !!" son binarias y valdrán 1 si el origen :! es asignado al destino ;" y 0 si no se da este caso. La principal diferencia de este modelo con el de transporte radica, por lo tanto, en la naturaleza de sus variables !!" . Además, en este modelo se asocian igual numero de orígenes que destinos. Se formula tal que: 12 *+,+-+./0$. =$ ) #!"#!!" !," (8) sujeto a $ ∑ !!" =1 ", i=1,2,…,n; (9) ∑!!" =1 !, j=1,2,…,m; (10) $!!" =0,1;$4/0/$5676$+,8. (11) Como se explica en (OpenCourseWare , s.f.), los costes de cada origen a cada destino vienen condensados en una matriz de costes, de misma estructura y naturaleza que la explicada para el problema de transporte. 2.8 El problema de transporte desequilibrado Para modelar el problema se han dado por hecho ciertas condiciones que bien podrían no cumplirse y afectarían a la resolución de este. Puede darse el caso de que el problema no esté balanceado. Recordando lo que se explico al definir el problema de transporte, esto se da cuando la oferta total de los orígenes no es igual a la demanda total de los destinos, es decir, ) %!≠ ) (" "! (12) Cuando esto ocurre, se deberán crear destinos u orígenes ficticios dependiendo del caso. Si la oferta total es mayor que la demanda total, es decir, ∑ %!> ∑ (""! , significa que hay parte de la oferta que se queda sin distribuir. Para resolverlo, se crea un destino ficticio que tendrá una demanda ficticia. (*,' = )%!− + !-' )(" #* "-' (13) Si la demanda total de los destinos es mayor que la oferta total de los orígenes, significa que la oferta no es capaz de satisfacer lo pedido y se deben crear orígenes ficticios que tendrán una oferta ficticia: %+,' =)("−$)%! + !-' #* "-' (14) 13 3. PROPUESTA DE CASO: LA LOGÍSTICA DE MERCADONA El objetivo principal de este trabajo es optimizar la distribución de los centros logísticos de la cadena Mercadona a sus supermercados, tanto a nivel provincial como regional. Para ello, se aplicará el modelo de transporte anteriormente explicado con el objetivo de minimizar el coste total. El modelo en cuestión adoptará la siguiente forma para el caso de estudio: 3.1 Variables En el marco teórico se explicó que las variables !!" eran las cantidades a ser transportadas. En este caso, serán camiones que llevarán la mercancía. Se supondrá que todo el material que se transporta es del mismo tipo para eliminar cualquier variable sobre el orden o la importancia de ser distribuido primero de ciertos productos. Por lo tanto, !!" =, equivaldrá a n camiones a ser transportados de i a j. 3.2 Nodos de origen y destino Los nodos origen serán los centros logísticos, que variarán dependiendo del caso de estudio en el que nos encontremos (provincial o regional). Los nodos destino serán los municipios que cuenten con al menos un supermercado de la cadena, y variarán con la misma lógica que los centros logísticos. Cada nodo de destino lleva asignada una demanda consigo. Para obtener los valores de la demanda se ha seguido la siguiente lógica. Hemos determinado que las variables !!" corresponden a camiones. Por lo tanto, tanto los valores de demanda como de oferta deberán tener la misma unidad. Para determinar la demanda, hemos definido que cada supermercado necesita un camión para ser abastecido. De esta manera, la demanda de un municipio con m supermercados será m. Los nodos de destino serán municipios y no supermercados porque los costes de transporte a cada uno de los supermarcados de un mismo municipio son prácticamente iguales, por lo tanto no se diferencian unos de otros y se agrupan. Los datos con los supermercados en cada municipio se obtienen de (Mercadona, 2021). Provienen de un documento que recoge todos los supermercados de la cadena que participaron en una recogida de alimentos con carácter solidario en 2021. En ella hay 1603 supermercados de los 1632 que hay en el país, por lo que es una muestra prácticamente idéntica a la realidad. Los centros logísticos que harán de nodos origen son los que aparecen en la figura 5. En cada caso de estudio se especificará cuáles son los escogidos. Para medir la oferta de cada centro logístico se ha elegido como dato la superficie construida de cada centro. Es una medida que refleja la capacidad de cada centro de abastecer y distribuir, de ahí su elección. Sin embargo, dado que se debe operar con las mismas unidades, habrá que transformar las unidades de superficie en número de camiones que puede proporcionar cada centro para distribuir el material. Para ello, se sigue la siguiente ecuación: 14 ,º#/-+6,HI!=I%4H0J+#+H$! I%4H0J+#+H$565/K∗7H-/,7/$565/K (15) Siendo I%4H0J+#+H$! la superficie del centro logístico, s %4H0J+#+H$565/K la suma de las superficies de los centros logísticos del caso en cuestión y 7H-/,7/$565/K el número total de camiones de demanda. De esta manera, estamos forzando a que el problema de transporte sea equilibrado y demanda total= oferta total. También se analizarán los casos en los que esto no ocurra y haya exceso de oferta o de demanda. Figura 5. Mapa con lo centros logísticos de Mercadona. Fuente:(Brines, 2018) Para el caso de la provincia de Sevilla, se escogen los centros de Huévar y Antequera. Se añade el de Guadix para el regional. Se explicará en cada caso el criterio de esta elección. El centro logístico de Huévar es el más grande de Andalucía al contar con 119700 metros cuadrados de superficie construida (Mercadona, 2018). Su reciente ampliación y modernización, en 2021, introdujo un sistema de Picking Puerto Grúa (PPG), un sistema innovador de preparación automática de palés. El objetivo de la automatización del proceso es delegar las labores exigentes físicamente en robots, como la recepción de mercancía o la preparación de palés, mejorando la eficiencia y reduciendo las lesiones de los trabajadores. 15 Figura 6. Centro logístico de Huévar. Fuente: (Mercadona, 2018) El centro de Antequera, de 45000 metros cuadrados construidos (Clemente, 2000), se inauguró en el año 2000 pero se han llevado a cabo remodelaciones y actuaciones de mejora y automatización por valor de 3,3 millones de euros (El Español, 2021) en el año 2021. Es el de menor superficie de los 3 que se tendrán en cuenta. El centro logístico de Guadix se inauguró en 2013 con una inversión de 60 millones de euros (Mercadona, 2013) y con 41000 metros cuadrados construidos y se divide en 5 naves para productos fríos, secos, tratamientos de envases, un edifico de servicios e incluso una fábrica de pan. También cuenta con el sistema PPG, como el de Huévar, que puede mover 30000 cajas de productos frescos en 6 horas según la web citada. Este bloque, como los otros, se unió al conjunto de mejoras llevadas a cabo en 2021 en todos los centros de Andalucía. En Guadix, se invirtieron más de 8 millones de euros para, entre otras cosas, edificar una nueva planta de congelados de 19200 metros cuadrados (Granada Hoy, 2021). Figura 7. Interior del centro logístico de Guadix. (Mercadona,2013) 16 3.3 Costes Gran parte de la problemática del caso radica en la elección de los costes. Se eligen dos casos distintos. Kilómetros en línea recta como coste Para el primer caso de estudio, se consideran como costes los kilómetros en línea recta entre los centros logísticos y los supermercados en cuestión. Es una elección que no tiene en cuenta la topografía del lugar y obvia carreteras y rutas. Sin embargo, se ha escogido por dos razones: • Para el caso provincial, es una buena medida para ser comparado posteriormente con los costes como kilómetros en carretera y ver como varía la función objetivo, es decir, el coste total. • Se usará también para el caso regional. Dado que no hay ningún programa que obtenga distancias en carretera entre municipios, y hacerlo a mano mediante Google Maps ocuparía mucho tiempo, se opta por calcular la distancia geodésica entre municipios. Estas si se pueden hallar mediante un programa de Python (que se adjunta en el anexo y de elaboración propia) que lee las coordenadas de los municipios y calcula las distancias entre estas y los centros logísticos. Las coordenadas se han obtenido mediante el geocodificador online (Willems, s.f.) del que se obtiene un listado de coordenadas geográficas al introducir la lista de localizaciones. Además, cabe resaltar que al calcular la distancia euclídea , despreciamos la curvatura de la tierra al trazar distancias sobre un plano. Sin embargo, al no recorrer distancias excesivas, podemos obviar este factor. Kilómetros en carretera como coste Se utiliza solo para uno de los casos en el estudio de abastecimiento provincial. Al abastecer solo 33 municipios y tener solo 2 nodos de origen, calcular la distancia en Google Maps no es especialmente largo. Entre todas las opciones, he escogido la que suponía menor distancia en kilómetros, sin tener en cuenta el tipo de vía (carretera, autopista, límites de velocidad, peajes...). Es un coste más cercano a la realidad que el anterior, al tratar con las rutas reales que hacen los transportistas. 3.4 Tipo de problema A lo largo de este trabajo se ha explicado la importancia de que el problema este balanceado o equilibrado. Sin embargo, se tratarán también los casos de exceso de demanda o de producción para evaluar la variación de los costes y analizar cuales son los centros logísticos y los supermercados críticos. 17 4. HERRAMIENTAS PARA LA RESOLUCIÓN DEL PROBLEMA DE TRANSPORTE 4.1 Solver de Excel. En los primeros casos se utilizará la herramienta Solver de Microsoft Excel. Se trata de un complemento de Excel que permite encontrar valores óptimos para fórmulas en celdas, sujetas a restricciones. De esta manera, se seleccionan las celdas que se deben rellenar para optimizar esa celda objetivo, siendo estas las variables del problema. La web de soporte de Microsoft establece un límite de 200 variables. Por lo tanto, para el análisis provincial del transporte, es una manera de resolver el problema. Para resolver el problema de transporte establecemos como función objetivo a minimizar la suma de los productos entre el número de camiones de cada centro a cada supermercado por el coste. Para ello, se habrá construido una tabla de costes con los datos rellenos (Tabla 4) y una tabla de flujos con los datos a rellenar (Tabla 5). Se utilizan los datos del primer caso que se resolverá, como ejemplo. 24 Tabla 7. Supermercados por municipio de la provincia. Fuente: Elaboración propia Municipios Número de supermercados Alcalá de Guadaíra 4 Alcalá del Río 1 Algaba, La 1 Arahal 1 Bormujos 2 Brenes 1 Cabezas de San Juan, Las 1 Camas 1 Cantillana 1 Carmona 1 Castilleja de la Cuesta 1 Coria del Río 2 Dos Hermanas 7 Écija 3 Espartinas 1 Estepa 1 Gines 1 Lebrija 1 Lora del Río 1 Mairena del Alcor 1 Mairena del Aljarafe 3 Marchena 1 Morón de la Frontera 2 Osuna 1 Palacios y Villafranca, Los 1 Pilas 1 La Rinconada 2 San Juan de Aznalfarache 2 Sanlúcar la Mayor 1 Sevilla 21 Tomares 2 Utrera 2 El Viso del Alcor 2 TOTAL 74 25 Costes Tabla 8. Distancia en línea recta entre centros logísticos y supermercados de la provincia. Fuente: Elaboración propia Distancia en km en línea recta Municipios Huevar Antequera Alcalá de Guadaíra 34,8 122,9 Alcalá del Río 28,7 139,2 La Algaba 23,0 140,0 Arahal 63,3 93,6 Bormujos 16,6 141,0 Brenes 38,5 131,9 Las Cabezas de San Juan 50,5 125,4 Camas 19,4 139,2 Cantillana 46,4 130,9 Carmona 54,4 109,7 Castilleja de la Cuesta 18,1 139,9 Coria del Río 19,7 137,9 Dos Hermanas 30,4 126,7 Écija 105,3 73,2 Espartinas 12,0 145,7 Estepa 121,3 42,2 Gines 15,0 142,6 Lebrija 52,0 138,3 Lora del Río 71,5 112,0 Mairena del Alcor 45,7 113,4 Mairena del Aljarafe 16,9 140,0 Marchena 74,3 84,5 Morón de la Frontera 76,0 81,8 Osuna 101,6 56,4 Los Palacios y Villafranca 36,0 125,6 Pilas 8,6 160,1 La Rinconada 28,6 135,6 San Juan de Aznalfarache 19,2 137,9 Sanlúcar la Mayor 4,9 153,2 Sevilla 22,3 135,7 Tomares 18,3 139,2 Utrera 45,6 112,8 El Viso del Alcor 47,7 112,0 26 Se observa que el supermercado más lejano del centro de Huévar es el de Estepa, mientras que el más lejano de Antequera es el de Pilas. El más cercano de Huévar es Sanlúcar la Mayor y el de Antequera, Estepa. Con estos datos, se procede a resolver el problema con el Solver de Excel como se ha descrito en el apartado 4.2, arrojando los siguientes resultados. Estos se representan en una tabla de transporte que, como se definió en el marco teórico, muestra las variables !!" . 27 Tabla 9. Solución de problema de transporte con la distribución de camiones a cada supermercado. Fuente: Elaboración propia. Municipios Huévar Antequera Alcalá de Guadaíra 3 1 Alcalá del Río 1 0 La Algaba 1 0 Arahal 0 1 Bormujos 2 0 Brenes 1 0 Las Cabezas de San Juan 0 1 Camas 1 0 Cantillana 0 1 Carmona 0 1 Castilleja de la Cuesta 1 0 Coria del Río 2 0 Dos Hermanas 7 0 Écija 0 3 Espartinas 1 0 Estepa 0 1 Gines 1 0 Lebrija 0 1 Lora del Río 0 1 Mairena del Alcor 0 1 Mairena del Aljarafe 3 0 Marchena 0 1 Morón de la Frontera 0 2 Osuna 0 1 Palacios y Villafranca, Los 1 0 Pilas 1 0 La Rinconada 2 0 San Juan de Aznalfarache 2 0 Sanlúcar la Mayor 1 0 Sevilla 21 0 Tomares 2 0 Utrera 0 2 El Viso del Alcor 0 2 Con un coste total de 3205,6 kilómetros. 28 La tabla se interpreta de la siguiente manera. Los 4 supermercados de Alcalá de Guadaira se abastecerán mediante un camión procedente del centro logístico de Antequera y 3 camiones del centro logístico de Huévar, siguiendo la misma lógica para los demás municipios. Del resultado obtenido concluimos que el centro logístico de Antequera cobra importancia para ciertos municipios de la provincia. Osuna, Marchena, Utrera y Morón de la Frontera, entre otros, se abastecen únicamente de este centro a pesar de encontrarse en otra provincia. La lejanía de estas localidades del Aljarafe, al menos hablando de distancia en línea recta sobre el mapa, justifica esta situación. Veremos mas adelante si lo hace también al variar el criterio de elección de los costes. La trayectoria de las carreteras y la existencia de autopistas podrán alterar esta distribución. La tabla siguiente resume la información mas característica de los resultados obtenidos Tabla 10. Tabla resumen caso provincial km línea recta. Fuente: Elaboración propia Máxima distancia (km) Mínima distancia (km) Distanci a total (km) Supermercados Abastecidos Localidades Abastecidas Distancia media camiones (km) Huévar 38,5 (Brenes) 4,9 (Sanlúcar la Mayor) 1243,8 54 19 23,0 Antequera 138,3 (Lebrija) 42,2 (Estepa) 1961,8 20 15 98,1 La razón por la que un camión deba recorrer 138,3 kilómetros para transportar material al supermercado de Lebrija solo se justifica por el hecho de que se hayan agotado los provenientes de Huévar y sea necesario recurrir a tan lejana opción. Sin embargo, resulta interesante destacar que aunque Huévar abastezca 34 establecimientos más, el número de localidades que abastece cada uno sea muy parejo. Esto quiere decir que el centro de Huévar abastece a localidades que aglutinan más supermercados como es el caso de Sevilla con 21, mientras que el de Antequera transporta a localidades que en su mayoría solo tienen un supermercado. De esta reflexión podemos extraer una conclusión. Si aumentásemos la capacidad de los camiones que parten de Huévar de tal forma que uno pueda dar cobertura a 3 supermercados, rebajaría mucho el coste porque son muchos los casos en los que muchos camiones deben ir a una sola localidad. El transporte dentro de la ciudad para abastecer a esos supermercados apenas tendría un coste de combustible ni de tiempo si se realiza en horarios con poco tráfico, como hace Mercadona. El coste de transporte a Dos Hermanas o Sevilla se rebajaría enormemente, ya que con la lógica actual necesitan 7 y 21 camiones respectivamente. No podríamos aplicar esta solución en Antequera, pues en su mayoría se tratan, como se ha comentado, de localidades con un único supermercado. Aunque aumentemos la capacidad de los camiones, como un camión solo va a una localidad, no mejoraría la solución más que en los casos de Écija, Utrera y Morón que si pueden verse favorecidos por esta situación. El dato de distancia media de camiones ofrece la media de las distancias que recorren los camiones que salen de cada uno de los centros logísticos. 29 5.1.1.2 Kilómetros en carretera como coste Los nodos de origen y destino no cambian. La tabla de costes cambia en este caso: Tabla 11. Distancia en carretera entre centros logísticos y supermercados de la provincia. Fuente: Elaboración propia Distancia en km en carretera Municipios Huévar Antequera Alcalá de Guadaíra 51,1 150,0 Alcalá del Río 44,8 184,0 La Algaba 36,7 172,0 Arahal 81,1 119,0 Bormujos 23,7 178,0 Brenes 52,0 166,0 Las Cabezas de San Juan 83,5 156,0 Camas 26,3 174,0 Cantillana 62,1 175,0 Carmona 66,6 143,0 Castilleja de la Cuesta 23,8 176,0 Coria del Río 29,6 181,0 Dos Hermanas 47,9 165,0 Écija 118,0 90,2 Espartinas 18,3 183,0 Estepa 147 53,6 Gines 20,7 180,0 Lebrija 96,1 173,0 Lora del Río 89,8 141,0 Mairena del Alcor 62,0 146,0 Mairena del Aljarafe 25,7 175,0 Marchena 97,6 109,0 Morón de la Frontera 100,0 104,0 Osuna 123,0 77,3 Los Palacios y Villafranca 58,4 157,0 Pilas 13,8 206,0 La Rinconada 41,3 180,0 San Juan de Aznalfarache 28,0 173,0 Sanlúcar la Mayor 10,5 195,0 Sevilla 31,0 172,0 Tomares 25,7 173,0 Utrera 62,5 142,0 El Viso del Alcor 65,1 149,0 30 Cambiando el criterio de costes, se observa que el supermercado más lejano del centro de Huévar sigue siendo el de Estepa y el de Antequera sigue siendo Pilas. Las localidades más cercanas también se mantienen aun cambiando el criterio.El Solver de Excel arroja los siguientes resultados: Tabla 12.Solución de problema de transporte con la distribución de camiones a cada supermercado. Fuente: Elaboración propia. Municipios Huévar Antequera Alcalá de Guadaíra 3 1 Alcalá del Río 1 0 La Algaba 1 0 Arahal 0 1 Bormujos 2 0 Brenes 1 0 Las Cabezas de San Juan 0 1 Camas 1 0 Cantillana 1 0 Carmona 0 1 Castilleja de la Cuesta 1 0 Coria del Río 2 0 Dos Hermanas 7 0 Écija 0 3 Espartinas 1 0 Estepa 0 1 Gines 1 0 Lebrija 0 1 Lora del Río 0 1 Mairena del Alcor 0 1 Mairena del Aljarafe 3 0 Marchena 0 1 Morón de la Frontera 0 2 Osuna 0 1 Los Palacios y Villafranca 0 1 Pilas 1 0 La Rinconada 2 0 San Juan de Aznalfarache 2 0 Sanlúcar la Mayor 1 0 Sevilla 21 0 Tomares 2 0 Utrera 0 2 El Viso del Alcor 0 2 31 Con un coste total de 4307,8 kilómetros. Como se ha cambiado el criterio para la elección de los costes, no es comparable con el caso anterior, pero es obvio que trazar las rutas de los camiones por carreteras sea más costoso que hacerlo en línea recta. El abastecimiento respecto al caso anterior cambia solo en Cantillana y Los Palacios y Villafranca. Esto hace indicar que el primer criterio, distancia en línea recta en un mapa, no es tan poco fiable como parece, asumiendo que los kilómetros en carretera/autovía es un coste realista y aplicable a la práctica. Los grafos construidos a partir de esta solución se han creado mediante el algoritmo del Programa 3. Este programa sitúa los nodos con coordenadas UTM, un sistema basado en la proyección cartográfica de Mercator. Es una proyección cilíndrica del globo terráqueo. Este código servirá como base para el resto de grafos y viene detallado en el anexo de este documento. Se representan grafos distintos para cada centro logístico, pues así se puede visualizar y analizar gráficamente el resultado. La figura 10 muestra la representación gráfica del abastecimiento desde el centro de Antequera. A continuación, en la figura 11 se aprecia el abastecimiento desde Huévar. La figura 12 representa el problema provincial total de abastecimiento, con ambos centros logísticos. Cabe destacar que solo se han representado aquellos arcos o conexiones por los que se envían camiones. Asimismo, sobre cada arco se ha escrito el número de camiones que recorren el mismo. El grafo con los dos centros se muestra para tener una idea general, pero el solapamiento de nombres y la lejanía entre municipios fuerza a que apenas podamos obtener información de este. Se insta al lector a recurrir a las tablas para conocer los datos. La geolocalización de los nodos origina la lejanía entre estos y su difícil lectura. 32 Figura 10. Grafo de abastecimiento del centro de Antequera. Caso Provincial y Equilibrado 33 Figura 11. Grafo de abastecimiento del centro de Huévar. Caso Provincial y Equilibrado 40 Figura 15. Grafo de abastecimiento del centro de Huévar. Caso Provincial y Exceso de Producción. 41 Figura 16. Grafos de las figuras 15 y 14 superpuestos 42 5.1.3 Exceso de demanda Otra situación para analizar es tener mayor demanda que oferta. Dado que el objetivo de este caso es ver cuáles son los supermercados que se verían afectados y desabastecidos por esta situación, no modificamos la demanda respecto al caso original. Sin embargo, disminuimos en un 10% la producción. Esto dejaría la demanda total en 67 camiones. !º#$%&'!()!=)+,(-.&#&(/! )+,(-.&#&(/0'0$1 ∗67 (17) Tabla 17. Tabla de nodos origen para exceso de demanda. Fuente: Elaboración propia Centros Logístico Superficie Construida Camiones Huévar 119700 49 Antequera 45000 18 TOTAL 164700 67 En el Solver, por el exceso de demanda, no será posible de cumplir la restricción de igualdad entre la demanda de los supermercados y lo que les abastece cada centro. Cambiamos el igual por un ≤ . Además, ya si podemos obligar a que todo lo ofertado por los centros sea abastecido, por lo que esta restricción recupera su signo de igualdad respecto al caso de exceso de producción. 43 Figura 17. Interfaz del Solver antes de ser ejecutado para problema exceso de demanda. Fuente: Elaboración propia 44 Tras ejecutar, se arroja la siguiente tabla con la distribución de camiones. Tabla 18.Solución de problema de transporte. Exceso de demanda. Fuente: Elaboración propia Municipios Huevar Antequera Alcalá de Guadaíra 0 2 Alcalá del Río 1 0 La Algaba 1 0 Arahal 0 1 Bormujos 2 0 Brenes 0 0 Las Cabezas de San Juan 0 0 Camas 1 0 Cantillana 0 0 Carmona 0 1 Castilleja de la Cuesta 1 0 Coria del Río 2 0 Dos Hermanas 7 0 Écija 0 3 Espartinas 1 0 Estepa 0 1 Gines 1 0 Lebrija 0 0 Lora del Río 0 1 Mairena del Alcor 0 1 Mairena del Aljarafe 3 0 Marchena 0 1 Morón de la Frontera 0 2 Osuna 0 1 Los Palacios y Villafranca 0 0 Pilas 1 0 La Rinconada 2 0 San Juan de Aznalfarache 2 0 Sanlúcar la Mayor 1 0 Sevilla 21 0 Tomares 2 0 Utrera 0 2 El Viso del Alcor 0 2 45 El coste total será de 3704,4 km. Este dato, sin embargo, no nos es de utilidad, porque hay supermercados que se quedan sin abastecer y no es comparable con los casos en los que si se reparte toda la demanda. Figura 18. Grafo de abastecimiento del centro de Antequera. Caso Provincial y Exceso de Demanda. 46 Figura 19. Grafo de abastecimiento del centro de Huévar. Caso Provincial y Exceso de Demanda De nuevo, el gráfico con ambos centros apenas se ve. Realmente, al tratarse de coordenadas geográficas, es difícil combinar una situación correcta de los nodos con una buena visibilidad. Por ello, se insiste en que es solo orientativa y para conocer el resultado se debe recurrir a las tablas anteriores. Los nodos en rojo son los centros desabastecidos. 47 Figura 20. Grafos de la figura 19 y 18 superpuestos 48 Es interesante ver cuáles son los 7 (diferencia entre los 74 de demanda y los 67 de oferta) que quedan desabastecidos. Para ello, ampliamos la información que recoge la tabla 19. Tabla 19. Comparación demanda y abastecido. Fuente: Elaboración propia Huevar Antequera TOTAL DEMANDA Alcalá de Guadaíra 0 2 2 4 Alcalá del Río 1 0 1 1 Algaba, La 1 0 1 1 Arahal 0 1 1 1 Bormujos 2 0 2 2 Brenes 0 0 0 1 Las Cabezas de San Juan 0 0 0 1 Camas 1 0 1 1 Cantillana 0 0 0 1 Carmona 0 1 1 1 Castilleja de la Cuesta 1 0 1 1 Coria del Río 2 0 2 2 Dos Hermanas 7 0 7 7 Écija 0 3 3 3 Espartinas 1 0 1 1 Estepa 0 1 1 1 Gines 1 0 1 1 Lebrija 0 0 0 1 Lora del Río 0 1 1 1 Mairena del Alcor 0 1 1 1 Mairena del Aljarafe 3 0 3 3 Marchena 0 1 1 1 Morón de la Frontera 0 2 2 2 Osuna 0 1 1 1 Los Palacios y Villafranca 0 0 0 1 Pilas 1 0 1 1 La Rinconada 2 0 2 2 San Juan de Aznalfarache 2 0 2 2 Sanlúcar la Mayor 1 0 1 1 Sevilla 21 0 21 21 Tomares 2 0 2 2 Utrera 0 2 2 2 El Viso del Alcor 0 2 2 2 49 De la tabla 19 se observa que Los Palacios, Lebrija, Cantillana, Las Cabezas de San Juan y Brenes quedarían sin abastecer. Todos estos son los únicos de la cadena en su respectivo municipio, por lo que obligaría a los ciudadanos a recurrir a otra cadena o a viajar a otro pueblo. Los otros 2 que quedan sin abastecer son los de Alcalá de Guadaira, pero al haber 4 en la localidad, no es especialmente crítica la situación. La razón por la que son esos los que quedan sin abastecer es. La figura muestra la disposición en el mapa de los municipios con los supermercados que quedan sin ser aprovisionados en azul y los centros logísticos en rojo. Forman una cadena de norte a sur de 60 km aproximadamente y no se aglutinan en una zona determinada. Figura 21. Distribución de supermercados sin abastecer. Fuente: Google Maps La solución a este problema se puede tratar de diversas maneras. Para evitar variar de forma exagerada el presupuesto del problema con la creación de un nuevo centro logístico en un punto cercano a estos, podemos cambiar el enfoque y ofrecer la posibilidad de utilizar un nuevo tipo de camión, más grande, que pueda abastecer a 2 supermercados. La elección de donde utilizar los camiones dobles se basa en el siguiente criterio. Tendremos que utilizarlo para las localidades más cercanas a Huevar, de esta manera, consumirá menos gasolina y aunque no tratemos los costos de adquirir ese tipo de camiones en este caso, supondrá una mejora notable. Además, suponemos que los nuevos camiones están disponibles en la flota de Huévar y Antequera y no hay que aumentar la oferta de los nodos de origen. Por lo tanto, para resolver el desabastecimiento actual: • La demanda de Alcalá pasa a ser de 2 camiones(grandes), ya que con esos 2 podremos abastecer los 4 supermercados 56 Níjar 364,2 209,7 90,6 Olula del Río 352,9 204,6 74,9 Vera 391,2 240,6 112,7 Vícar 327,9 171,7 68,9 Algeciras 155,1 127,0 244,0 Arcos de la Frontera 78,4 115,5 245,8 Barbate 133,0 152,6 277,5 Cádiz 95,9 128,9 258,3 Chiclana 104,3 156,5 285,6 Conil de la Frontera 120,3 159,4 286,7 El Puerto de Santa María 84,5 156,5 286,6 Jerez 75,3 144,3 274,6 La Línea de la Concepción 155,9 118,0 234,1 Los Barrios 147,8 124,5 243,7 Medina-Sidonia 103,5 136,8 265,6 Puerto Real 91,7 155,2 285,1 Rota 80,2 165,4 295,7 San Fernando 99,4 159,2 288,7 San Roque 150,0 116,2 234,2 Sanlúcar de Barrameda 64,3 161,5 291,4 Tarifa 160,6 145,5 262,6 Ubrique 105,7 87,5 216,7 Villamartín 78,8 98,0 228,1 Aguilar de la Frontera 144,7 55,4 136,6 Baena 175,5 69,8 110,7 Cabra 163,2 51,4 117,1 Córdoba 144,9 98,2 159,2 Fernán Núñez 141,8 73,7 146,4 Hinojosa del Duque 161,3 172,0 221,3 La Carlota 123,7 78,9 164,2 Lucena 158,9 43,8 120,2 Montilla 147,4 63,1 136,6 Montoro 183,1 112,7 136,4 Palma del Río 96,2 98,5 194,6 Peñarroya-Pueblonuevo 137,8 155,2 218,1 Pozoblanco 169,6 152,8 192,4 Priego de Córdoba 184,4 56,4 95,3 Puente Genil 134,0 44,8 144,8 Rute 169,3 37,8 109,3 Albolote 233,4 84,3 46,2 Almuñécar 239,0 82,6 80,1 Armilla 235,9 83,4 47,8 57 Atarfe 229,9 80,4 50,0 Baza 310,8 167,1 38,7 Chauchina 222,8 72,3 58,0 Churriana de la Vega 234,7 82,6 48,3 Granada 251,2 99,0 33,2 Guadix 278,5 130,3 5,6 Huétor Tájar 198,8 49,9 81,4 La Zubia 240,6 87,6 44,5 Las Gabias 232,8 80,4 50,6 Loja 190,1 40,1 91,0 Maracena 234,8 84,6 45,7 Monachil 244,4 91,8 40,3 Motril 254,6 97,8 69,7 Nigüelas 247,0 91,2 50,3 Ogíjares 238,3 85,4 46,4 Otura 237,2 83,4 49,6 Peligros 234,5 85,1 45,2 Pinos Puente 224,3 76,4 54,8 Pulianas 237,5 88,0 42,3 Salobreña 248,9 92,2 73,3 Santa Fe 227,8 77,3 53,0 Aljaraque 66,8 220,4 344,7 Almonte 23,6 175,8 299,8 Ayamonte 100,8 253,4 378,4 Aracena 64,6 201,6 309,5 Bollullos Par del Condado 23,1 179,1 301,6 Cartaya 78,1 232,2 356,2 Cortegana 78,2 223,0 332,3 Gibraleón 61,1 217,2 339,6 Huelva 66,4 222,2 339,7 La Palma 24,5 181,4 302,8 Lepe 82,7 236,1 360,6 Moguer 50,2 203,9 328,0 Punta Umbría 63,9 214,5 340,0 Valverde del Camino 48,5 203,8 321,5 Alcalá la Real 208,8 74,8 72,0 Andújar 210,7 121,8 115,1 Baeza 257,7 144,9 82,7 Bailén 235,5 138,0 104,8 Jaén 258,8 145,9 82,7 Villacarrillo 293,8 178,2 90,7 Linares 247,3 144,7 98,5 58 Mancha Real 240,7 119,8 68,4 Martos 207,8 93,4 87,2 Torredonjimeno 210,6 98,7 88,7 Úbeda 266,7 152,5 82,2 Alhaurín de la Torre 171,0 39,9 145,3 Alhaurín el Grande 162,1 43,7 156,4 Algarrobo 209,5 54,1 99,1 Álora 151,9 25,2 149,0 Antequera 156,9 4,2 130,3 Archidona 170,2 17,5 113,4 Benahavis 143,4 70,0 190,5 Benalmádena 174,0 47,1 149,4 Campillos 130,2 27,0 155,8 Cártama 163,3 34,6 147,7 Coín 155,9 43,6 160,7 Estepona 144,0 84,0 203,6 Fuengirola 172,5 53,2 157,0 Málaga 176,8 35,6 134,8 Manilva 142,1 94,2 214,4 Marbella 151,4 67,8 184,9 Mijas 168,9 47,6 154,5 Nerja 224,3 68,3 88,7 Rincón De La Victoria 191,9 42,2 119,9 Ronda 120,0 61,6 190,4 Torremolinos 177,7 43,9 142,4 Torrox 217,2 61,6 94,0 Vélez-Málaga 204,1 49,2 103,2 Alcalá De Guadaira 39,2 118,7 239,3 Alcalá Del Rio 32,1 137,4 252,9 Arahal 65,9 91,3 213,5 Bormujos 18,3 139,8 260,3 Brenes 41,9 130,2 243,7 Camas 22,3 137,2 256,8 Cantillana 49,2 129,6 240,2 Carmona 57,2 108,5 223,3 Castilleja De La Cuesta 20,7 138,1 258,2 Coria Del Rio 21,4 135,7 258,5 Dos Hermanas 32,5 124,4 247,0 Écija 107,9 73,8 174,2 El Viso Del Alcor 49,8 110,6 228,9 Espartinas 13,2 145,2 265,7 Estepa 124,4 41,3 154,3 59 Gines 17,9 140,8 261,0 La Rinconada 30,1 136,2 252,8 Las Cabezas De San Juan 51,3 122,6 251,4 Lebrija 51,6 135,3 264,6 Lora Del Rio 74,3 111,2 215,4 Los Palacios y Villafranca 38,2 122,2 247,9 Mairena Del Alcor 46,8 112,5 231,8 Mairena Del Aljarafe 19,7 137,9 258,8 Marchena 76,5 83,2 202,1 Morón De La Frontera 77,6 80,2 206,6 Osuna 104,6 54,2 175,0 Pilas 6,2 157,4 280,3 San Juan De Aznalfarache 21,2 136,4 257,3 Sanlúcar La Mayor 7,7 151,0 271,6 Sevilla 26,7 132,2 252,1 Tomares 21,0 137,3 257,7 Utrera 48,0 109,9 234,9 5.2.1 Problema equilibrado Establecemos las capacidades de los nodos origen para el problema equilibrado, forzando a que la suma de las ofertas de los centros logísticos iguale a la suma de las demandas, 318 camiones. Esto se hace como en el caso provincial, mediante la ecuación 15, pero adaptada a este caso. !º#$%&'!()!=)+,(-.&#&(/! )+,(-.&#&(/0'0$1 ∗318 Resultando en la tabla 23, que resume toda esta información. Tabla 23. Capacidad de los centros logísticos para el caso regional. Fuente: Elaboración propia Centros Logístico Superficie Construida Camiones Huévar 119700 169 Antequera 45000 64 Guadix 60200 85 TOTAL 224900 318 (18) Resolución del problema Teniendo ya los datos de costes, oferta y demanda podemos resolver el problema. Como se ha comentado, por la magnitud del problema en lo referente al alto número de variables y restricciones, nos apoyamos en la programación. Abordaremos el problema de transporte con restricciones usando Python. El código se estructura de la siguiente manera: 60 En primer lugar, se importa la librería pandas para poder leer los ficheros en Excel; y el conjunto de paquetes Pyomo. Por comodidad, la función SolverFactory incluida en Pyomo es importada explícitamente, pues así es posible tenerla localizadas cuando realicemos la elección del solver. Comenzamos leyendo el archivo de Excel (en formato xlsx) con la librería pandas, especificando la hoja donde se hallan los datos que vamos a necesitar. Es preciso tener en cuenta que para facilitar el tratamiento de datos, la columna de la izquierda debe reservarse para la designación numérica de las filas. Acto seguido, creamos una lista (N) cuya longitud se corresponderá con la longitud de las columnas leídas inicialmente. Haciendo uso de este parámetro, creamos diccionarios que contengan las localidades origen y destino, así como sus coordenadas. Repetimos el proceso (leyendo la hoja correspondiente) para crear diccionarios que contengan los datos de oferta y demanda. Asimismo, creamos un diccionario que contenga los costes (distancias calculadas) desde cada centro logístico hasta cada posible destino. Por último, creamos diccionarios para las capacidades de oferta y demanda. Es preciso tener en cuenta que sólo estamos considerando tres centros logísticos en Andalucía, por lo que el diccionario Ofertas tendrá únicamente los tres primeros elementos como no nulos. Una vez leídos y definidos los datos, comenzamos a hacer uso de Pyomo. El primer paso en cualquier problema de optimización es definir el modelo (por simplicidad, llamado "modelo"). La función ConcreteModel() indica que estamos comenzando a definir un modelo. Dado que vamos a abordar un problema de transporte, es preciso crear los nodos de oferta (centros logísticos) y demanda (destinos). Usando la nomenclatura habitual en Pyomo, los datos de oferta para el modelo los definimos mediante el subíndice i, mientras que los de salida los definimos mediante el subíndice j. Usamos la función Set para ello, cuyo argumento principal —initialize— precisa especificar las listas que habremos creado previamente. Respecto a estas listas, la nomenclatura es la siguiente: initialize = [lista]. La primera lista la creamos manualmente, pues sólo tiene tres elemenos (los tres origenes). La segunda lista es la que contiene todas las localidades destino. Para usar tal información, extraemos los valores del diccionario "Localidad_destino", usando la funcion .values(). Una vez hecho esto, convertimos el resultado en una lista usando list(). La lista final se llama Localidad_destino_lst. Tras definir los nodos de oferta y demanda, definimos las capacidades de oferta y demanda. Para ello, crearemos un diccionario que se componga de: {Localidad_destino: Demandas}. Para poder hacer eso, lo mas cómodo es convertir los dos diccionarios implicados a listas (que designamos por _lst). Acto seguido, usamos la funcion zip. Definimos las capacidades de oferta y demanda mediante la función Param de pyomo, utilizando las letras a y b como designación, y los modelos i,j descritos antes como principal argumento. Llegados a este punto, nuestro siguiente objetivo es crear un diccionario cuyo key-value sea la tupla (origen, destino) y el valor sea el coste calculado. Vamos a iterar sobre una lista (Localidad_destino_lst) cuyos componentes son 'strings'. La forma de hacer eso es por 'for i in range(len(LISTA)):'. Si lo hiciéramos con 'for i in LISTA:' obtendríamos el siguiente error: TypeError: list indices must be integers or slices, not str. Se trata de un error habitual en Python, que no se obtiene cuando la lista contiene sólo elementos numéricos. Dado que queremos un gran diccionario final con todos los costes, por comodidad crearemos tres listas origen-destino (cada una con un origen) haciendo uso de bucles, y luego las uniremos. Una vez hecho esto, convertimos en listas los tres diccionarios de costes creados al principio. Acto seguido, uniremos las tres listas, y la uniremos a la lista 'Ori_dests', creando finalmente un nuevo diccionario. Nuevamente, usaremos la funcion 'zip' para crear el nuevo diccionario a partir de las dos listas: 'Ori_dests' y 'Costes_todos_lst'. 61 En este punto, crearemos una nueva variable para el modelo (designando con la letra d), nuevamente usando los nodos de origen (i) y destino (j) como argumentos, para almacenar los costes de transporte (km recorridos). Para poder trabajar con estos datos, definiremos una función 'f_costo' que tome los argumentos anteriores junto con los datos almacenados del modelo, y devuelva un diccionario bidimensional con los costes [i,j] del modelo, de cara a poder realizar los cálculos. Definimos una nueva entrada cuyos argumentos sean, además de los modelos i,j, un 'initialize = f_costo', almacenando los costes de transporte en un espacio bidimensional. Por último, es preciso definir una variable (x) cuyo significado es 'cantidad de producto distribuido'. Esta variable se usa mas adelante, al imponer las restricciones. Fijando todo lo anterior como base, imponemos las restricciones del problema. Una de las ventajas de Pyomo es poder escribir explícitamente las ecuaciones que definen las diferentes restricciones, que en nuestro caso serán: a) Cantidad máxima de producto ofertado. b) Cantidad máxima de producto demandado. Estas restricciones actuarán sobre la función objetivo, que la definimos a continuación y cuyo único argumento es el modelo definido inicialmente. Gracias a esto, podemos hacer uso de la función Objetive de Pyomo, donde podremos especificar que el solver actúe sobre la función definida y que nuestro objetivo es minimizar los costes (existiendo otras opciones, dependiendo del problema). Ya definidas variables, función objetivo y restricciones, podemos resolver el problema e imprimir los resultados haciendo uso de la función display. Se utiliza el solver glpk (GNU Linear Programming Kit), que invocamos mediante la función SolverFactory importada al principio del programa. En último lugar, usaremos la función opt de pyomo sobre nuestro modelo, y finalmente la función pyomo_postprocess para obtener directamente los resultados optimizados en nuestro modelo de transporte. El resultado que se obtiene por consola es la cantidad transportada desde cada centro logístico a cada municipio. El código de este programa viene adjunto en el anexo como Programa 3. Para facilitar la lectura y la compresión, se divide el resultado total en 3 tablas, una para cada centro logístico. A diferencia de el caso provincial, se filtra y se omiten las filas donde no se abastece nada a un municipio. 62 Tabla 24. Camiones abastecidos desde el centro de Antequera. Fuente: Elaboración propia Destino Cantidad Algarrobo 1 Alhaurín de la Torre 3 Alhaurín el Grande 1 Antequera 4 Archidona 1 Benalmádena 3 Cártama 1 Fuengirola 3 Huétor Tájar 1 Loja 1 Málaga 23 Mijas 4 Nerja 2 Priego de Córdoba 2 Rincón de la Victoria 2 Rute 1 Torremolinos 5 Torrox 1 Vélez-Málaga 4 Álora 1 63 Tabla 25. Camiones abastecidos desde el centro de Guadix. Fuente: Elaboración propia Destino Cantidad Destino Cantidad Adra 2 Maracena 1 Albolote 1 Martos 1 Albox 1 Mojácar 1 Alcalá la Real 1 Monachil 1 Almería 9 Motril 2 Almuñécar 2 Nigüelas 1 Andújar 1 Níjar 1 Armilla 1 Ogíjares 1 Atarfe 1 Olula del Río 1 Baeza 1 Otura 1 Bailén 1 Peligros 1 Baza 1 Pinos Puente 1 Berja 1 Pulianas 1 Carboneras 1 Roquetas de Mar 2 Chauchina 1 Salobreña 1 Churriana de la Vega 1 Santa Fe 1 Cuevas del Almanzora 1 Torredonjimeno 1 El Ejido 4 Vera 2 Las Gabias 1 Villacarrillo 1 Garrucha 1 Vícar 1 Granada 13 Úbeda 2 Guadix 1 Linares 2 Huercal Overa 1 Mancha Real 1 Huércal de Almería 2 La Zubia 1 Jaén 5 La Mojonera 1 64 Tabla 26. Camiones abastecidos desde el centro de Huévar. Fuente: Elaboración propia Destino Cantidad Destino Cantidad Destino Cantidad Aguilar de la Frontera 1 Moguer 1 Montilla 1 Alcalá de Guadaira 4 Coín 1 Montoro 1 Alcalá del Río 1 Dos Hermanas 5 Morón de la Frontera 2 Algeciras 5 El Puerto de Santa María 2 Osuna 1 Aljaraque 1 El Viso del Alcor 1 Palma del Río 1 Almonte 1 Espartinas 1 Peñarroya- Pueblonuevo 1 Andújar 1 Estepa 1 Pilas 1 Aracena 1 Estepona 5 Pozoblanco 1 Arahal 1 Fernán Núñez 1 Puente Genil 1 Arcos 2 Gibraleón 1 Puerto Real 2 Ayamonte 1 Gines 1 Punta Umbría 1 Baena 1 Hinojosa del Duque 1 La Rinconada 1 Barbate 1 Huelva 5 Ronda 2 Benahavís 1 Jerez 3 Rota 1 Bollullos Par del Condado 1 La Carlota 1 San Fernando 3 Bormujos 2 La Línea de la Concepción 4 San Juan de Aznalfarache 2 Brenes 1 La Palma 1 San Roque 2 Cabra 1 Las Cabezas de San Juan 1 Sanlúcar de Barrameda 1 Cadiz 1 Lebrija 1 Sanlúcar la Mayor 1 Camas 1 Lepe 1 Sevilla 20 Campillos 1 Lora del Río 1 Tarifa 1 Cantillana 1 Los Barrios 2 Tomares 2 Carmona 1 Los Palacios y Villafranca 1 Ubrique 1 Cartaya 1 Lucena 2 Utrera 3 Castilleja de la Cuesta 1 Mairena del Alcor 1 Valverde del Camino 1 Chiclana 4 Mairena del Aljarafe 3 Villamartín 1 Conil de la Frontera 1 Manilva 1 Écija 3 Córdoba 12 Marbella 6 Cortegana 1 Coria del Río 2 Marchena 1 Medina- Sidonia 1 65 Siendo el valor de la función objetivo 22998,9. Es decir, para abastecer a toda Andalucía los camiones deben recorrer esa distancia en kilómetros. Los grafos presentados a continuación tienen la función de orientar al lector del número de localidades abastecidas. La geolocalización de los nodos y el alto número de municipios hace imposible construir grafos perfectamente legibles y coherentes. Por ello, para leer los datos se debe acudir a las tablas anteriores. 72 La figura 28 muestra el abastecimiento total de toda Andalucía, con los 3 centros logísticos y sus respectivos arcos. Como era previsible por su capacidad, el radio de influencia de Huévar es muy amplio, llegando a municipios como Andújar (Jaén). La figura 24 permite ver todo el área de acción del centro logístico, y la figura 25, aunque haya solapamientos de letras, ofrece la posibilidad de identificar los nodos más lejanos. El desarrollo que está teniendo la provincia de Málaga y la Costa del Sol en particular, desbancando incluso a Sevilla como puntal tecnológico y turístico del sur de España, provoca que no pueda ser abastecido solo por el centro de Antequera. Resulta curioso que, aun teniendo un centro en su propia provincia, haga tanto uso del centro de Huévar, llegando incluso a transportar 6 camiones a Marbella. Esto se debe principalmente a la poca capacidad de Antequera, no estando a la altura este centro de la situación privilegiada que está viviendo la zona. Se deben seguir llevando labores de ampliación y actualización para que no sea necesario recurrir a Huévar. Algunos datos de interés que se extraen de las tablas anteriores son: Tabla 27.Tabla resumen caso regional y equilibrado. Fuente: Elaboración propia Centros logísticos Máxima distancia (km) Mínima distancia (km) Distancia total (km) Localidades Abastecidas Supermercados Abastecidos Distancia media camiones (km) Huévar Andújar (210,7) 6,2 (Pilas) 14652,2 87 169 86,4 Antequera Nerja (68,3) Antequera (4,2) 2561,2 20 64 39,8 Guadix Garrucha (117,6) Guadix (5,6) 5785,5 50 85 68,1 Como aclaración, se observa que para el caso provincial el supermercado más cercano a Huévar era el de Sanlúcar la Mayor. La razón por la que ahora es Pilas es simplemente por el cambio en la herramienta de medición de distancias. Para el caso provincial se utilizó Google Maps y se midió entre el centro logístico y el supermercado. Al cambiar al caso regional, y por el volumen de datos a manejar, optamos por usar el Programa 1. Este mide localidades entre si, y no tiene en cuenta que el centro logístico de Huévar no se encuentra en el núcleo urbano de la población, si no un poco alejado. De ahí surge la discordancia, que no deja de ser una curiosidad puntual. Los camiones que salen de Huévar, por ser este el centro logístico más grande, lideran el total de la operación de transporte y son los que más kilómetros hacen de media. Los salientes de Antequera, sin embargo, abastecen a supermercados cercanos hasta agotarse su oferta, siendo la distancia media que estos recorren menos de la mitad que los de Huévar. Los supermercados de las provincias de Huelva, Sevilla y Cádiz son exclusivamente abastecidos por el centro de Huévar. 73 El centro de Antequera abastece a localidades de la provincia de Málaga y Córdoba. El de Guadix, a supermercados de Jaén, Almería y Granada. El de Huévar reparte a Sevilla, Cádiz, Málaga, Córdoba y Jaén. La media de las distancias medias desde cada centro resulta en 64,8 kilómetros. Es decir, de media, un camión de Mercadona debe hacer 64,8 kilómetros para abastecer su supermercado objetivo. 5.2.2 Exceso de producción Se trata el caso de exceso de producción. Se analiza el problema en el que la producción es un 10% mayor respecto a la demanda. Por lo tanto, siendo la demanda de 318 camiones, la oferta pasa a ser 350. Hay que ajustar, de este modo, las capacidades de los centros logísticos para que sumen 350 y sea siempre acorde a su superficie. Haciendo uso de las mismas ecuaciones que para el caso anterior, imponemos la ecuación 19. !º#$%&'!()!=)+,(-.&#&(/! )+,(-.&#&(/0'0$1 ∗350 (19) Resultando la siguiente tabla: Tabla 28. Capacidad de los centros logísticos. Caso regional con exceso de producción. Fuente: Elaboración propia Centros Logístico Superficie Construida Camiones Huévar 119700 186 Antequera 45000 70 Guadix 60200 94 TOTAL 224900 350 En este caso, debemos modificar el código del Programa 2 para cambiar una de las restricciones. Como se vio en el caso provincial, cuando hay exceso de producción, no se puede cumplir la restricción de que se abastezca todo lo que se produce, pues infringiría la restricción de que los supermercados deben ser abastecidos con su demanda, sin superarla. Por ello, modificamos la función f_oferta en el código para cambiar la condición de igualdad. La nueva condición será que la cantidad que es abastecida por un centro es menor o igual a la capacidad de este, tal que: def f_oferta(modelo, i): return sum(modelo.x[i,j] for j in modelo.j) <= modelo.a[i] Además, habría que sustituir los nuevos valores de oferta en la lectura de los datos de oferta. Resultando en el siguiente resultado. 74 Tabla 29.Camiones abastecidos desde el centro de Antequera Exceso Producción. Fuente: Elaboración propia Destino Cantidad Aguilar de la Frontera 1 Algarrobo 1 Alhaurín de la Torre 3 Alhaurín el Grande 1 Antequera 4 Archidona 1 Benalmádena 3 Cabra 1 Campillos 1 Coín 1 Cártama 1 Fuengirola 3 Loja 1 Lucena 2 Malaga 23 Marbella 4 Mijas 4 Montilla 1 Puente Genil 1 Rincón de la Victoria 2 Rute 1 Torremolinos 5 Vélez-Málaga 4 Álora 1 75 Tabla 30. Camiones abastecidos desde el centro de Guadix Exceso Producción. Fuente: Elaboración propia Destino Cantidad Destino Cantidad Adra 2 La Zubia 1 Albolote 1 Linares 2 Albox 1 Mancha Real 1 Alcalá la Real 1 Maracena 1 Almeria 9 Martos 1 Almuñécar 2 Mojacar 1 Andújar 2 Monachil 1 Armilla 1 Montoro 1 Atarfe 1 Motril 2 Baena 1 Nerja 2 Baeza 1 Nigüelas 1 Bailén 1 Níjar 1 Baza 1 Ogíjares 1 Berja 1 Olula del Río 1 Carboneras 1 Otura 1 Chauchina 1 Peligros 1 Churriana de la Vega 1 Pinos Puente 1 Cuevas del Almanzora 1 Priego de Córdoba 2 El Ejido 4 Pulianas 1 Las Gabias 1 Roquetas de Mar 2 Garrucha 1 Salobreña 1 Granada 13 Santa Fe 1 Guadix 1 Torredonjimeno 1 Huercal Overa 1 Torrox 1 Huércal de Almería 2 Vera 2 Huétor Tájar 1 Villacarrillo 1 Jaén 5 Vícar 1 La Mojonera 1 Úbeda 2 76 Tabla 31. Camiones abastecidos desde el centro de Huévar. Exceso Producción. Fuente: Elaboración propia Destino Cantidad Destino Cantidad Destino Cantidad Alcalá de Guadaira 4 Gines 1 Punta Umbría 1 Alcalá del Río 1 Hinojosa del Duque 1 La Rinconada 1 Algeciras 5 Huelva 5 Ronda 2 Aljaraque 1 Jerez 3 Rota 1 Almonte 1 La Carlota 1 San Fernando 3 Aracena 1 La Línea de la Concepción 4 San Juan de Aznalfarache 2 Arahal 1 La Palma 1 San Roque 2 Arcos 2 Las Cabezas de San Juan 1 Sanlúcar de Barrameda 1 Ayamonte 1 Lebrija 1 Sanlúcar la Mayor 1 Barbate 1 Lepe 1 Sevilla 20 Benahavís 1 Lora del Río 1 Tarifa 1 Bollullos Par del Condado 1 Los Barrios 2 Tomares 2 Bormujos 2 Los Palacios y Villafranca 1 Ubrique 1 Brenes 1 Mairena del Alcor 1 Utrera 3 Cádiz 1 Mairena del Aljarafe 3 Valverde del Camino 1 Camas 1 Manilva 1 Villamartín 1 Cantillana 1 Marbella 2 Écija 3 Carmona 1 Marchena 1 Espartinas 1 Cartaya 1 Medina- Sidonia 1 Estepa 1 Castilleja de la Cuesta 1 Moguer 1 Pozoblanco 1 Chiclana 4 Morón de la Frontera 2 Puerto Real 2 Conil de la Frontera 1 Osuna 1 Estepona 5 Córdoba 12 Palma del Río 1 Fernán Núñez 1 Coria del Río 2 Peñarroya- Pueblonuevo 1 Gibraleón 1 Cortegana 1 Pilas 1 Dos Hermanas 5 El Puerto de Santa María 2 El Viso del Alcor 1 77 Siendo el coste total de la solución 21819,6 km. Se reduce el coste respeto al caso equilibrado. Esto se debe esencialmente a que al tener más capacidad, los centros podrán abastecer a los supermercados que mejor les convenga. En el caso equilibrado, muchos transportes eran el resultado de que un centro cercano a un supermercado no podía aprovisionarlo por haber agotado su capacidad, y este tenía que ser abastecido por otro más lejano, incrementando el coste total. Analizando los camiones que no son utilizados se obtiene la siguiente tabla: Tabla 32. Análisis exceso de producción. Fuente: Elaboración propia Centro Logístico Capacidad Camiones que abastece Huévar 186 154 Antequera 70 70 Guadix 94 94 El centro logístico de Antequera utiliza todos sus camiones, al igual que le de Guadix. Los 32 camiones de exceso de producción serán los que no salgan del centro de Huévar. Esto repercute de la siguiente manera: Tabla 33. Tabla resumen caso regional y exceso de producción. Fuente: Elaboración propia Centros logísticos Máxima distancia (km) Mínima distancia (km) Distancia total (km) Localidades Abastecidas Supermercados Abastecidos Distancia media camiones (km) Huévar Pozoblanco (169,6) 6,2 (Pilas) 12284,1 77 154 79,8 Antequera Marbella (67,8) Antequera (4,2) 2844,4 24 70 40,6 Guadix Montoro (136,4) Guadix (5,6) 6691,1 56 94 71,2 La media entre las distancias medias que cada camión recorre desde cada centro resulta en 63,8 km. Por lo tanto, el exceso de producción prácticamente no varía la distancia media de todos los camiones. Además, la máxima distancia que recorren los camiones de los centros solo disminuye para los de Huévar. Los de Antequera apenas varían y los de Guadix incrementan. Ocurre algo similar con las distancias medias, que incrementan para los camiones de Guadix, se mantienen prácticamente para los de Antequera y disminuyen para Huévar. Aun así, producir un 10% más y tener en cuenta que esa sobreproducción se reparte equitativamente respecto a los bloques logísticos y sus superficies ahorra al proceso total de transporte 1179.3 kilómetros. 5.2.3 Exceso de demanda En este caso, analizamos el efecto del exceso de demanda. Para no modificar los datos de demanda, pues implicaría alterar el número de supermercados por municipio, reducimos la oferta actual en un 10%, resultando en la siguiente tabla: 78 Tabla 34. Capacidad de los centros logísticos. Caso regional con exceso de demanda. Fuente: Elaboración propia Centros Logístico Superficie Construida Camiones Huévar 119700 152 Antequera 45000 57 Guadix 60200 77 TOTAL 224900 286 De nuevo, debemos modificar las restricciones. Al tener un 10 % más de demanda que de oferta, no todos los supermercados podrán ser abastecidos, y la restricción que obliga a suplir todos los supermercados con su demanda carecería de sentido. Por ello, en el Programa 2 debemos cambiar la restricción para permitir que lo que les llegue a los supermercados sea el valor de su demanda o un valor menor que esta. El código quedaría intacto, pero modificando: def f_demanda(modelo, j): return sum(modelo.x[i,j] for i in modelo.i) <= modelo.b[j] Además, habría que sustituir los nuevos valores de oferta en la lectura de los datos de oferta. El resultado obtenido sería el siguiente: Tabla 35. Camiones abastecidos desde el centro de Antequera. Exceso demanda. Fuente: Elaboración propia Destino Cantidad Alhaurín de la Torre 3 Alhaurín el Grande 1 Antequera 4 Archidona 1 Benalmádena 3 Coín 1 Cártama 1 Loja 1 Lucena 2 Málaga 23 Mijas 4 Rincón de la Victoria 2 Rute 1 Torremolinos 5 Vélez-Málaga 4 Álora 1 79 Tabla 36. Camiones abastecidos desde el centro de Guadix. Exceso demanda. Fuente: Elaboración propia Destino Cantidad Destino Cantidad Adra 2 La Zubia 1 Albolote 1 Mancha Real 1 Albox 1 Maracena 1 Alcalá la Real 1 Martos 1 Almería 9 Monachil 1 Almuñécar 2 Motril 2 Armilla 1 Nerja 2 Atarfe 1 Nigüelas 1 Baeza 1 Níjar 1 Baza 1 Ogíjares 1 Berja 1 Olula del Río 1 Chauchina 1 Otura 1 Churriana de la Vega 1 Peligros 1 El Ejido 4 Pinos Puente 1 Las Gabias 1 Pulianas 1 Granada 13 Roquetas de Mar 2 Guadix 1 Salobreña 1 Huércal de Almería 2 Santa Fe 1 Huétor Tájar 1 Torredonjimeno 1 Jaén 5 Villacarrillo 1 La Mojonera 1 Vícar 1 Úbeda 2 80 Tabla 37.Camiones abastecidos desde el centro de Huévar. Exceso demanda. Fuente: Elaboración propia Destino Cantidad Destino Cantidad Destino Cantidad Aguilar de la Frontera 1 La Palma 1 Fernán Núñez 1 Alcalá de Guadaira 4 Las Cabezas de San Juan 1 Gibraleón 1 Alcalá del Río 1 Lebrija 1 Gines 1 Algeciras 2 Lepe 1 Huelva 5 Aljaraque 1 Lora del Río 1 Jerez 3 Almonte 1 Los Barrios 2 La Carlota 1 Aracena 1 Los Palacios y Villafranca 1 Ubrique 1 Arahal 1 Mairena del Alcor 1 Utrera 3 Arcos 2 Mairena del Aljarafe 3 Valverde del Camino 1 Ayamonte 1 Manilva 1 Villamartín 1 Barbate 1 Marbella 6 Écija 3 Benahavís 1 Marchena 1 El Viso del Alcor 1 Bollullos Par del Condado 1 Medina-Sidonia 1 Espartinas 1 Bormujos 2 Moguer 1 Estepa 1 Brenes 1 Montilla 1 Estepona 5 Cádiz 1 Morón de la Frontera 2 Sanlúcar de Barrameda 1 Camas 1 Osuna 1 Sanlúcar la Mayor 1 Campillos 1 Palma del Río 1 Sevilla 20 Cantillana 1 Peñarroya- Pueblonuevo 1 Tomares 2 Carmona 1 Pilas 1 El Puerto de Santa María 2 Cartaya 1 Puente Genil 1 San Roque 2 Castilleja de la Cuesta 1 Puerto Real 2 Dos Hermanas 5 Chiclana 4 Punta Umbría 1 San Juan de Aznalfarache 2 Conil de la Frontera 1 La Rinconada 1 Cortegana 1 Córdoba 12 Ronda 2 San Fernando 3 Coria del Río 2 Rota 1 81 El coste total del transporte, y por tanto, el valor de la función objetivo, es de 18819 kilómetros. Este valor, sin embargo, no es de especial interés. Su bajo valor se debe a que no abastece a todos los supermercados y por lo tanto, no cumple con el objetivo de la estrategia logística. Aislando los supermercados que quedan sin abastecer resulta la siguiente tabla: Tabla 38. Supermercados sin abastecer. Caso regional. Fuente: Elaboración propia. Destino Provincia Demanda Transportado Supermercados no abastecidos Algarrobo Málaga 1 0 1 Algeciras Cádiz 5 2 3 Andújar Jaén 2 0 2 Baena Córdoba 1 0 1 Bailén Jaén 1 0 1 Cabra Córdoba 1 0 1 Carboneras Almería 1 0 1 Cuevas del Almanzora Almería 1 0 1 Fuengirola Málaga 3 0 3 Garrucha Almería 1 0 1 Hinojosa del Duque Córdoba 1 0 1 Huércal Overa Almería 1 0 1 La Línea de la Concepción Cádiz 4 0 4 Linares Jaen 2 0 2 Mojácar Almería 1 0 1 Montoro Córdoba 1 0 1 Pozoblanco Córdoba 1 0 1 Priego de Córdoba Córdoba 2 0 2 Tarifa Cádiz 1 0 1 Torrox Málaga 1 0 1 Vera Almería 2 0 2 32 Los 32 supermercados que quedan sin abastecer coinciden con la diferencia entre la demanda (318) y la oferta (286) lo cual indica una buena resolución del problema. Estos se ubican en 21 diferentes municipios. Es destacable que los supermercados de Sevilla, Granada y Huelva no tienen problemas de desabastecimiento. Este fenómeno puede darse por encontrarse el centro de Huévar a escasos kilómetros de la provincia onubense pero a su vez cerca de los municipios sevillanos a abastecer. El pleno abastecimiento de los supermercados granadinos puede darse también por la ventajosa situación geográfica del centro de Guadix en su provincia, que se muestra en el mapa posterior, y del hecho de contar con un centro en una provincia limítrofe como es el de Antequera. 88 Mercadona. (s.f.). Obtenido de https://info.mercadona.es/es/supermercados Mercadona. (18 de Octubre de 2013). Obtenido de Mercadona: https://info.mercadona.es/es/actualidad/mercadona-pone-en-marcha-su-nuevo- bloque-logistico-en-guadix-granada-0/news Mercadona. (13 de Agosto de 2018). Obtenido de https://info.mercadona.es/es/actualidad/mercadona-invertira-35-millones-de- euros-en-la-ampliacion-de-su-bloque-logistico-de-huevar/news Mercadona. (Noviembre de 2021). Obtenido de https://info.mercadona.es/document/es/listado-tiendas-participantes-de- mercadona-en-la-gran-recogida-2021.pdf?blobheader=application/pdf Mercadona. (2021 de Junio de 2021). Recuperado el Junio de 2022, de https://info.mercadona.es/es/conocenos/sala-de-prensa/hemeroteca/mercadonaamplia-su-bloque-logistico-de-san-isidro-alicante-con-una-inversion-total-de- 98-millones-de-euros/news Miranda, F. (28 de Junio de 2021). La Estrategia del Ocho para que no haya viajes de vacío. Diario Jaen. Muñuzuri, J., Onieva, L., Cortés, P., Guadix, J., & Ibañez, J. N. (2010). Métodos Cuantitativos y Organización de la Producción. Madrid: Sintesis. OpenCourseWare . (s.f.). Obtenido de OpenCourseWare : https://ocw.ehu.eus/pluginfile.php/41788/mod_resource/content/1/6._transporte_ asignacion.pdf Or, S. (19 de Noviembre de 2020). PTV Group. Obtenido de https://blog.ptvgroup.com/es/ciudad-y-movilidad/reducir-costos-de-transporte- logistica/ Orús, A. (Enero de 2022). Obtenido de https://es.statista.com/estadisticas/540894/porcentaje-de-ventas-de-los-grandes- supermercados-en-espana/ Palau, J. C. (27 de Octubre de 2020). El Mercantil. Obtenido de https://elmercantil.com/2020/10/27/mercadona-alcanza-la-plena-ocupacion-de- sus-camiones-gracias-a-la-logistica-inversa/ Pandey, A. (s.f.). Math Ideas That Click! . Obtenido de https://www.anshoo.in/2021/05/shortest-linear-distance-vs-geodesic.html Pedregal, P. (2003). Introduction to Optimization, vol. 46. Springer. Schrijver, A. (2002). On the History of the Transportation and Maximum Flow Problems. Mathematical Programming(91), 437-445. Shilpa, P., Jagadeesh, D., & Kumar, R. A. (s.f.). Shokrhy, S., & Tanaka, S. (2018). Bandwidth Maximization Approach for Displaced Left-Turn Crossovers Coordination under Heterogeneous Traffic Conditions. Journal of Traffic and Transportation Engineering, 183-196. Tafakkori, K. (29 de Diciembre de 2021). Supply Chain Data Analytics. Obtenido de https://www.supplychaindataanalytics.com/es/modelado-y-resolucion-de- problemas-de-optimizacion-en-python/ Verschik, A. M. (2013). Long History of the Monge-Kantorovich Transportation Problem. The Mathematical Intelligencer volume , 35, 1-9. Vershik, A. M. (2006). KANTOROVICH METRIC: INITIAL HISTORY AND LITTLE-KNOWN APPLICATIONS. Journal of Mathematical Sciences, 133(4), 1410-1417. Willems, E. (s.f.). Geocode Local Focus. Obtenido de https://geocode.localfocus.nl 89 ANEXO. CÓDIGOS DE PYTHON Programa 1. Cálculo de distancias geodésicas entre centros logísticos supermercados. from geopy.distance import geodesic import pandas import numpy as np print('Leyendo datos') df = pandas.read_excel('DATOS MERCADONA TFG BIS1.xlsx', sheet_name='Coordenadas', header=0, index_col=[0]) N = list(df.index.map(int)) # Localidad_destino: Localidad_destino = {(i): df.at[i, 'Localidad_destino'] for i in N} # X_destino: X_destino = {(i): df.at[i, 'X_destino'] for i in N} # y_destino: Y_destino = {(i): df.at[i, 'Y_destino'] for i in N} # Localidad_origen: Localidad_origen = {(i): df.at[i, 'Localidad_origen'] for i in N} # X_origen: X_origen = {(i): df.at[i, 'X_origen'] for i in N} # Y_origen: Y_origen = {(i): df.at[i, 'Y_origen'] for i in N} # - Documentacion: https://geopy.readthedocs.io/en/stable/ # Se definen los orígenes: Huevar = (X_origen[1], Y_origen[1]) Guadix = (X_origen[2], Y_origen[2]) Antequera = (X_origen[3], Y_origen[3]) print('Las distancias desde Huevar son: ') print(' ') for i in X_destino: print(geodesic(Huevar,(X_destino[i],Y_destino[i]))) print(' ') print('Las distancias desde Guadix son: ') print(' ') for i in X_destino: print(geodesic(Guadix,(X_destino[i],Y_destino[i]))) 90 print('Las distancias desde Antequera son: ') print(' ') for i in X_destino: print(geodesic(Antequera,(X_destino[i],Y_destino[i]))) Programa 2. Resolución del problema de transporte para el caso regional. import pyomo.environ as pe from pyomo.opt import SolverFactory import pandas as pd from pyomo.environ import value # Se crea la variable df que contiene los datos del problema: df = pd.read_excel('DATOS MERCADONA TFG BIS1.xlsx', sheet_name='Coordenadas', header=0, index_col=[0]) N = list(df.index.map(int)) # Localidad_destino: Localidad_destino = {(i): df.at[i, 'Localidad_destino'] for i in N} # X_destino: X_destino = {(i): df.at[i, 'X_destino'] for i in N} # y_destino: Y_destino = {(i): df.at[i, 'Y_destino'] for i in N} # Localidad_origen: Localidad_origen = {(i): df.at[i, 'Localidad_origen'] for i in N} # X_origen: X_origen = {(i): df.at[i, 'X_origen'] for i in N} # Y_origen: Y_origen = {(i): df.at[i, 'Y_origen'] for i in N} dg = pd.read_excel('DATOS MERCADONA TFG BIS1.xlsx', sheet_name='OferDem', header=0, index_col=[0]) # Se lee la hoja con los costes (distancias calculadas) dentro del Excel. dc = pd.read_excel('DATOS MERCADONA TFG BIS1.xlsx', sheet_name='Costes', header=0, index_col=[0]) # Se define un diccionario para los costes (distancias) desde cada #localidad hasta cada posible destino: Costes_Huevar = {(i): dc.at[i, 'Huevar'] for i in N} Costes_Antequera = {(i): dc.at[i, 'Antequera'] for i in N} 91 Costes_Guadix = {(i): dc.at[i, 'Guadix'] for i in N} # Capacidades_oferta: Ofertas = {(i): dg.at[i, 'Oferta'] for i in N} # Capacidades_demanda: Demandas = {(i): dg.at[i, 'Demanda'] for i in N} # Se crea el modelo con Pyomo: modelo = pe.ConcreteModel() '''Se crean los nodos de oferta (centros logísticos) y demanda (destinos): La nomenclatura es la siguiente: initialize = [lista]. La primera lista se crea manualmente, pues solo tiene tres elemenos (los tres orígenes). La segunda lista es la que contiene todas las localidades destino. Para usar tal informacion, se extraen los valores del diccionario "Localidad_destino", usando la funcion .values(). Una vez hecho esto, convertimos el resultado en una lista usando list(). La lista final se #llama Localidad_destino_lst. ''' Localidad_origen_lst = list(Localidad_origen.values())[0:3] Ofertas_lst = list(Ofertas.values())[0:3] Localidad_destino_lst = list(Localidad_destino.values()) Demandas_lst = list(Demandas.values()) modelo.i = pe.Set(initialize=[Localidad_origen[1],Localidad_origen[2],Localidad_orig en[3]], doc='Origenes') modelo.j = pe.Set(initialize=Localidad_destino_lst[:], doc = 'Destinos') '''El objetivo es tenerun diccionario que se componga de: {Localidad_destino: Demandas}. Para poder hacer eso, lo mas cómodo es convertir los dos diccionarios implicados a listas (que designamos por _lst). Acto seguido, usamos la función zip''' Origen_y_oferta = dict(zip(Localidad_origen_lst, Ofertas_lst)) Destino_y_demanda = dict(zip(Localidad_destino_lst, Demandas_lst)) # Se definen las capacidades de oferta y demanda: modelo.a = pe.Param(modelo.i, initialize=Origen_y_oferta, doc='Capacidad de oferta de cada centro logistico') modelo.b = pe.Param(modelo.j, initialize=Destino_y_demanda, doc='Demanda de cada Mercadona') #El objetivo es crear una nomenclatura como la de la funcion 'costos' #definida mas abajo, sin necesidad de escribir todos los casos #manualmente. 92 # El primer elemento del diccionario es una tupla con dos elementos no #numericos (strings). ''' Se itera sobre una lista (Localidad_destino_lst) cuyos componentes son strings. La forma de hacer eso es por 'for i in range(len(LISTA)):'. Si lo hicieramos con 'for i in LISTA:' obtendriamos el siguiente error: TypeError: list indices must be integers or slices, not str. Eso solo podriamos hacerlo si la lista contuviese elementos numericos''' '''Por comodidad, antes de unirlo todo en un super-diccionario de costes final, vamos a crear tres listas Origen-Destinos. Cada una con un origen''' ### Huevar ### # Se la siguiente lista de listas: # [['Huevar', 'Destino_1'],['Huevar', 'Destino_2']['Huevar', ....]] Ori_dest_1 = [] # Se comienza definiendo la lista vacia. El bucle lo que #va a hacer es rellenarla, mediante la funcion append. for i in range(len(Localidad_destino_lst)): Ori_dest_Huevar = Ori_dest_1.append([Localidad_origen_lst[0],Localidad_destino_lst[i]]) print(Ori_dest_1) ### Antequera ### # Se la siguiente lista de listas: # [['Antequera', 'Destino_1'],['Antequera', 'Destino_2']['Antequera', #....]] Ori_dest_2 = [] # Se comienza definiendo la lista vacia. El bucle lo que #va a hacer es rellenarla, mediante la funcion append. for i in range(len(Localidad_destino_lst)): Ori_dest_Antequera = Ori_dest_2.append([Localidad_origen_lst[2],Localidad_destino_lst[i]]) print(Ori_dest_2) ### Guadix ### # Se crea la siguiente lista de listas: # [['Guadix', 'Destino_1'],['Guadix', 'Destino_2']['Guadix', ....]] Ori_dest_3 = [] # Se comienaza definiendo la lista vacia. El bucle lo que # va hacer es rellenarla, mediante la funcion append. for i in range(len(Localidad_destino_lst)): Ori_dest_Guadix = Ori_dest_3.append([Localidad_origen_lst[1],Localidad_destino_lst[i]]) 93 print(Ori_dest_3) # Se crea una lista Origen - Destinos que agrupe las tres listas # creadas arriba: Ori_dests = (Ori_dest_1 + Ori_dest_2 + Ori_dest_3) tuples = [tuple(x) for x in Ori_dests] # Se convierten en listas los tres diccionarios de costes creados al @ #principio.Acto seguido, se unen las tres listas, y se unen a #Ori_dests, creando finalmente un nuevo diccionario. Costes_Huevar_lst = list(Costes_Huevar.values()) Costes_Antequera_lst = list(Costes_Antequera.values()) Costes_Guadix_lst = list(Costes_Guadix.values()) Costes_todos_lst = Costes_Huevar_lst + Costes_Antequera_lst+ Costes_Guadix_lst # Se usa la funcion 'zip' para crear el nuevo diccionario a partir de # las dos listas: Ori_dests y Costes_todos_lst: Costes = dict(zip(tuples, Costes_todos_lst)) modelo.d = pe.Param(modelo.i, modelo.j, initialize=Costes, doc='Costo de transporte (km recorridos)') # Coste de transporte (distancia; en nuestro caso, km recorridos): def f_costo(modelo, i, j): return modelo.d[i,j] modelo.c = pe.Param(modelo.i, modelo.j, initialize=f_costo, doc='Costo de transporte (km recorridos)') #definimos variable x con las cantidades de camiones enviados # Es preciso definir una variable (x) cuyo significado es 'cantidad de #producto distribuido'. Esta variable se usa mas adelante, al imponer las #res-tricciones: modelo.x = pe.Var(modelo.i, modelo.j, bounds=(0.0,None), doc='Cantidad de producto') # Se impone las restricciones del problema. # Cantidad maxima de producto ofertado: def f_oferta(modelo, i): return sum(modelo.x[i,j] for j in modelo.j) == modelo.a[i] modelo.oferta = pe.Constraint(modelo.i, rule=f_oferta, doc='Máximo ofertado por cada centro logistico') # Cantidad maxima de producto demandado: 94 def f_demanda(modelo, j): return sum(modelo.x[i,j] for i in modelo.i) == modelo.b[j] modelo.demanda = pe.Constraint(modelo.j, rule=f_demanda, doc='Máximo demandado por cada Mercadona') # Definicion de la funcion objetivo: def f_objetivo(modelo): return sum(modelo.c[i,j]*modelo.x[i,j] for i in modelo.i for j in modelo.j) modelo.objetivo = pe.Objective(rule=f_objetivo, sense=pe.minimize, doc='Función Objetivo') # Resolución del problema e impresión de resultados def pyomo_postprocess(options=None, instance=None, results=None): modelo.x.display() # En este caso, se usa el solver glpk. Pyomo permite usar otros. # https://pyomo.readthedocs.io/en/stable/solving_pyomo_models.html opt = SolverFactory("glpk") resultados = opt.solve(modelo) # Resultados: print("\Solución óptima encontrada\n" + '-'*80) pyomo_postprocess(None, None, resultados) print("\Valor función objetivo es\n", value(modelo.objetivo)) Programa 3. Creación de grafos con coordenadas UTM # FUENTE DE LAS COORDENADAS UTM: # https://www.dices.net/ # (DIRECTORIO CARTOGRÁFICO DE ESPAÑA Y AMÉRICA) from math import sqrt import matplotlib import matplotlib.pyplot as plt import networkx as nx import pandas as pd class Dupla: def _init_(self, x, y): self.x = x self.y = y def CalcDis(Dup1, Dup2): return sqrt(pow((Dup1.x - Dup2.x), 2) + pow((Dup1.y - Dup2.y), 2)) #calcula la distancia entre dos puntos G = nx.Graph() # Se crea un grafo nulo 95 vertices_G = ['Huevar','Alcalá de Guadaira','Alcalá del Río','La Algaba','Bormujos','Brenes', 'Camas','Cantillana','C.C.','Coria del Río', 'Dos Hermanas','Espartinas','Gines', 'Mairena del Aljarafe','Pilas', 'La Rinconada','San Juan','Sanlúcar la Mayor', 'Sevilla','Tomares'] # Se crean todos los vertices G.add_nodes_from(vertices_G) Pesos_G = [('3'),('1'),('1'),('2'),('1'),('1'),('1'),('1'),('2'),('7'), ('1'),('1'),('3'),('1'),('2'),('2'),('1'),('21'),('2')] aristas_G = [('Huevar', 'Alcalá de Guadaira'), ('Huevar', 'Alcalá del Río'), ('Huevar', 'La Algaba'), ('Huevar', 'Bormujos'), ('Huevar', 'Brenes'), ('Huevar', 'Camas'), ('Huevar', 'Cantillana'), ('Huevar', 'C.C.'), ('Huevar', 'Coria del Río'), ('Huevar', 'Dos Hermanas'), ('Huevar', 'Espartinas'), ('Huevar', 'Gines'), ('Huevar', 'Mairena del Aljarafe'), ('Huevar', 'Pilas'), ('Huevar', 'La Rinconada'), ('Huevar', 'San Juan'),('Huevar', 'Sanlúcar la Mayor'), ('Huevar', 'Sevilla'), ('Huevar', 'Tomares')] zipped = dict(zip(aristas_G,Pesos_G)) # Se crean todas las aristas: G.add_edges_from(aristas_G) ubica = {'Huevar': (210692,4140625.5), 'Alcalá de Guadaira': (248967,4135684.9), 'Alcalá del Río': (236319,4156441.5), 'La Algaba': (233194,4150986.2), 'Bormujos': (228409,4140030.6), 'Brenes': (246746,4159819.9), 'Camas': (231481,4143634.6), 'Cantillana': (251330,4165235.4), 'C.C.': (229946,4141832.5), 'Coria del Río': (229447,4130985.5), 'Dos Hermanas': (240750,4130504.6), 'Espartinas': (224041,4142025.6), 'Gines': (228470,4141880.4), 'Mairena del Aljarafe': (228289,4136331.1), 'Pilas': (207639,4133632.1), 'La Rinconada': (237676,4152695.3), 'San Juan': (231362,4139935.1), 'Sanlúcar la Mayor': (216661,4142272.9), 'Sevilla': (235508,4140975.5), 'Tomares': (231422,4141784.9) } 96 # Se crea un diccionario con los datos decada vertice y su ubicacion en #el plano X Y. Despues, se asignan los valores X Y de cada vertice #extrayendolos del diccionario: puntoA = Dupla() puntoA.x = ubica['Huevar'][0] puntoA.y = ubica['Huevar'][1] puntoC = Dupla() puntoC.x = ubica['Alcalá de Guadaira'][0] puntoC.y = ubica['Alcalá de Guadaira'][1] puntoD = Dupla() puntoD.x = ubica['Alcalá del Río'][0] puntoD.y = ubica['Alcalá del Río'][1] puntoE = Dupla() puntoE.x = ubica['La Algaba'][0] puntoE.y = ubica['La Algaba'][1] puntoG = Dupla() puntoG.x = ubica['Bormujos'][0] puntoG.y = ubica['Bormujos'][1] puntoH = Dupla() puntoH.x = ubica['Brenes'][0] puntoH.y = ubica['Brenes'][1] puntoJ = Dupla() puntoJ.x = ubica['Camas'][0] puntoJ.y = ubica['Camas'][1] puntoK = Dupla() puntoK.x = ubica['Cantillana'][0] puntoK.y = ubica['Cantillana'][1] puntoM = Dupla() puntoM.x = ubica['C.C.'][0] 97 puntoM.y = ubica['C.C.'][1] puntoN = Dupla() puntoN.x = ubica['Coria del Río'][0] puntoN.y = ubica['Coria del Río'][1] puntoO = Dupla() puntoO.x = ubica['Dos Hermanas'][0] puntoO.y = ubica['Dos Hermanas'][1] puntoQ = Dupla() puntoQ.x = ubica['Espartinas'][0] puntoQ.y = ubica['Espartinas'][1] puntoS = Dupla() puntoS.x = ubica['Gines'][0] puntoS.y = ubica['Gines'][1] puntoW = Dupla() puntoW.x = ubica['Mairena del Aljarafe'][0] puntoW.y = ubica['Mairena del Aljarafe'][1] puntoBeta = Dupla() puntoBeta.x = ubica['Pilas'][0] puntoBeta.y = ubica['Pilas'][1] puntoGamma = Dupla() puntoGamma.x = ubica['La Rinconada'][0] puntoGamma.y = ubica['La Rinconada'][1] puntoDelta = Dupla() puntoDelta.x = ubica['San Juan'][0] puntoDelta.y = ubica['San Juan'][1] puntoEpsilon = Dupla() puntoEpsilon.x = ubica['Sanlúcar la Mayor'][0] puntoEpsilon.y = ubica['Sanlúcar la Mayor'][1]