Optimización de redes logísticas y procesos industriales mediante IBM ILOG CPLEX
Introducción
Una Empresa Petrolífera dispone de 5 refinerías repartidas por la península con una capacidad conjunta de procesado de 770.000 barriles por día (BPD). Tras garantizar el estocaje estratégico y los bombeos para CLH, todavía disponen de 320.000 BPD para libre distribución según indica la tabla 1.
El transporte se realizará a la red de gasolineras de las diferentes comunidades autónomas (exceptuando Islas Baleares, Islas Canarias, Ceuta y Melilla) mediante la flota de camiones cisterna propia de la compañía.
El gerente de la compañía ha solicitado un informe de optimización de transporte según el criterio de demanda de las diferentes comunidades autónomas y el coste del transporte.
Modelo matemático
El objetivo es minimizar costes cumpliendo con la demanda, donde:
- RF: Refinería.
- CA: Comunidad autónoma.
- CosteP: Coste de la producción.
- CosteT: Coste del transporte.
- RFOrigen: Refinería de origen.
- DemandaporRF: Demanda por refinería.
A continuación debemos plantear las restricciones que nos plantean la demanda y la capacidad.
Modelo OPL
Archivo .mod
/********************************************* * OPL 12.6.0.0 Model * Author: GMM * Creation Date: Jan/2016 *********************************************/ //Índices {string} Productos =…; {string} RF =…; //Refinería {string} CA =…; //Comunidad Autónoma // Datos float Demanda[CA][Productos] =…; float CosteP [RF] =…; float CosteT[RF][CA] =…; float Capacidad_RFd [RF] =…; float Capacidad_RFg [RF] =…; // Variables dvar float+ DemandaporRF[CA][RF][Productos]; dvar boolean RFOrigen[RF]; // Función Objetivo minimize sum(r in RF) CosteP[r] * RFOrigen[r] + sum(c in CA, r in RF, p in Productos) CosteT [r][c]*DemandaporRF[c][r][p]; //Restricciones subject to { forall (c in CA, p in Productos) sum(r in RF) DemandaporRF[c][r][p] == Demanda [c][p]; forall (r in RF) sum (c in CA, p in Productos) DemandaporRF[c][r][p]<= (Capacidad_RFd [r] * RFOrigen[r]) + (Capacidad_RFg [r] * RFOrigen[r]); }
Si el planteamiento del modelo matemático lo hacemos bien, la función objetivo es fiel. Como resultado final, obtenemos el coste de la distribución desde el almacén óptimo.
- Modelo matemático
- Función objetivo
minimize sum(r in RF) CosteP[r] * RFOrigen[r] + sum(c in CA, r in RF, p in Productos) CosteT [r][c]*DemandaporRF[c][r][p];
Las restricciones hacen referencia a la demanda y a la capacidad.
subject to { forall (c in CA, p in Productos) sum(r in RF) DemandaporRF[c][r][p] == Demanda [c][p]; forall (r in RF) sum (c in CA, p in Productos) DemandaporRF[c][r][p]<= (Capacidad_RFd [r] * RFOrigen[r]) + (Capacidad_RFg [r] * RFOrigen[r]); forall (r in RF) RFOrigen[r]<=1; }
- La restricción de la demanda exige que para todas las comunidades autónomas y productos, la demanda debe ser satisfecha para la refinería seleccionada.
... forall (c in CA, p in Productos) sum(r in RF) DemandaporRF[c][r][p] == Demanda [c][p]; ...
- La restricción de la capacidad exige que la demanda desde cada refinería a cada comunidad autónoma y de cada producto, no supere la capacidad de dicha refinería.
... forall (r in RF) sum (c in CA, p in Productos) DemandaporRF[c][r][p]<= (Capacidad_RFd [r] * RFOrigen[r]) + (Capacidad_RFg [r] * RFOrigen[r]); ...
Archivo de datos
Archivo .dat
//Conexión con la hoja de cálculo SheetConnection sheet("RedLogistica01.xlsx"); // Datos de la hoja Excel Productos from SheetRead(sheet,"Hoja1!A2:A3"); RF from SheetRead(sheet,"Hoja1!A6:A10"); CA from SheetRead(sheet,"Hoja1!A14:A28"); Demanda from SheetRead(sheet,"Hoja1!B14:C28"); CosteP from SheetRead(sheet,"Hoja1!B6:B10"); Capacidad_RFd from SheetRead(sheet,"Hoja1!C6:C10"); Capacidad_RFg from SheetRead(sheet,"Hoja1!D6:D10");
Conexión con Excel
Debido a que se manejan numerosos datos, utilizaremos una hoja Excel con el fin de agilizar el proceso. La hoja Excel se llama RedLogistica01.xlsx y se encuentra en la misma ruta que el modelo y el archivo de datos. Primeramente se establece conexión para posteriormente indicarle a CPLEX los rangos de celdas que contienen los datos.
Solución OPL
Cplex arroja un coste optimizado de 7.908.676,09€. También nos indica que todas las refinerías transportarán algo mediante la variable RFOrigen y nos detalla los envíos mediante la variable DemandaporRF. Ya que en esta solución los datos no se ven correctamente, pasaremos a analizarlos en el siguiente apartado.
Interpretación de la solución
Podemos obtener la relación de orígenes y destinos mediante la vista de datos de la variable DemandaporRF como refleja la tabla 4.
CA (tamaño 15) | RF (tamaño 5) | Productos (tamaño 2) | Valor |
---|---|---|---|
Castilla y León | Bilbao | Gasolina | 15000 |
Castilla y León | Bilbao | Diesel | 14400 |
Galicia | Coruña | Diesel | 14200 |
Andalucía | Puertollano | Diesel | 14000 |
Extremadura | Tarragona | Diesel | 13200 |
Cataluña | Tarragona | Diesel | 13000 |
Aragón | Puertollano | Diesel | 13000 |
Castilla-La Mancha | Coruña | Diesel | 11800 |
Comunidad Valenciana | Cartagena | Diesel | 11700 |
Castilla-La Mancha | Coruña | Gasolina | 10000 |
Extremadura | Tarragona | Gasolina | 9550 |
País Vasco | Bilbao | Diesel | 9200 |
Comunidad Foral de Navarra | Bilbao | Diesel | 9100 |
Cataluña | Tarragona | Gasolina | 9100 |
Cantabria | Bilbao | Diesel | 8500 |
Comunidad Foral de Navarra | Bilbao | Gasolina | 8000 |
Región de Murcia | Cartagena | Diesel | 7200 |
Comunidad de Madrid | Cartagena | Diesel | 7000 |
Aragón | Tarragona | Gasolina | 7000 |
La Rioja | Bilbao | Gasolina | 6500 |
Principado de Asturias | Coruña | Diesel | 6000 |
Galicia | Coruña | Gasolina | 6000 |
Andalucía | Puertollano | Gasolina | 6000 |
Principado de Asturias | Coruña | Gasolina | 5000 |
Comunidad Valenciana | Cartagena | Gasolina | 3450 |
La Rioja | Bilbao | Diesel | 3200 |
Región de Murcia | Cartagena | Gasolina | 3000 |
Cantabria | Bilbao | Gasolina | 2600 |
Comunidad de Madrid | Cartagena | Gasolina | 2400 |
La Rioja | Tarragona | Diesel | 1850 |
País Vasco | Bilbao | Gasolina | 1500 |
Castilla-La Mancha | Cartagena | Diesel | 1500 |
Aragón | Tarragona | Diesel | 300 |
La Rioja | Cartagena | Diesel | 150 |
Región de Murcia | Puertollano | Gasolina | 0 |
Región de Murcia | Puertollano | Diesel | 0 |
Región de Murcia | Tarragona | Gasolina | 0 |
Región de Murcia | Tarragona | Diesel | 0 |
Región de Murcia | Bilbao | Gasolina | 0 |
Región de Murcia | Bilbao | Diesel | 0 |
Región de Murcia | Coruña | Gasolina | 0 |
Región de Murcia | Coruña | Diesel | 0 |
Principado de Asturias | Cartagena | Gasolina | 0 |
Principado de Asturias | Cartagena | Diesel | 0 |
Principado de Asturias | Puertollano | Gasolina | 0 |
Principado de Asturias | Puertollano | Diesel | 0 |
Principado de Asturias | Tarragona | Gasolina | 0 |
Principado de Asturias | Tarragona | Diesel | 0 |
Principado de Asturias | Bilbao | Gasolina | 0 |
Principado de Asturias | Bilbao | Diesel | 0 |
País Vasco | Cartagena | Gasolina | 0 |
País Vasco | Cartagena | Diesel | 0 |
País Vasco | Puertollano | Gasolina | 0 |
País Vasco | Puertollano | Diesel | 0 |
País Vasco | Tarragona | Gasolina | 0 |
País Vasco | Tarragona | Diesel | 0 |
País Vasco | Coruña | Gasolina | 0 |
País Vasco | Coruña | Diesel | 0 |
La Rioja | Cartagena | Gasolina | 0 |
La Rioja | Puertollano | Gasolina | 0 |
La Rioja | Puertollano | Diesel | 0 |
La Rioja | Tarragona | Gasolina | 0 |
La Rioja | Coruña | Gasolina | 0 |
La Rioja | Coruña | Diesel | 0 |
Galicia | Cartagena | Gasolina | 0 |
Galicia | Cartagena | Diesel | 0 |
Galicia | Puertollano | Gasolina | 0 |
Galicia | Puertollano | Diesel | 0 |
Galicia | Tarragona | Gasolina | 0 |
Galicia | Tarragona | Diesel | 0 |
Galicia | Bilbao | Gasolina | 0 |
Galicia | Bilbao | Diesel | 0 |
Extremadura | Cartagena | Gasolina | 0 |
Extremadura | Cartagena | Diesel | 0 |
Extremadura | Puertollano | Gasolina | 0 |
Extremadura | Puertollano | Diesel | 0 |
Extremadura | Bilbao | Gasolina | 0 |
Extremadura | Bilbao | Diesel | 0 |
Extremadura | Coruña | Gasolina | 0 |
Extremadura | Coruña | Diesel | 0 |
Comunidad Valenciana | Puertollano | Gasolina | 0 |
Comunidad Valenciana | Puertollano | Diesel | 0 |
Comunidad Valenciana | Tarragona | Gasolina | 0 |
Comunidad Valenciana | Tarragona | Diesel | 0 |
Comunidad Valenciana | Bilbao | Gasolina | 0 |
Comunidad Valenciana | Bilbao | Diesel | 0 |
Comunidad Valenciana | Coruña | Gasolina | 0 |
Comunidad Valenciana | Coruña | Diesel | 0 |
Comunidad Foral de Navarra | Cartagena | Gasolina | 0 |
Comunidad Foral de Navarra | Cartagena | Diesel | 0 |
Comunidad Foral de Navarra | Puertollano | Gasolina | 0 |
Comunidad Foral de Navarra | Puertollano | Diesel | 0 |
Comunidad Foral de Navarra | Tarragona | Gasolina | 0 |
Comunidad Foral de Navarra | Tarragona | Diesel | 0 |
Comunidad Foral de Navarra | Coruña | Gasolina | 0 |
Comunidad Foral de Navarra | Coruña | Diesel | 0 |
Comunidad de Madrid | Puertollano | Gasolina | 0 |
Comunidad de Madrid | Puertollano | Diesel | 0 |
Comunidad de Madrid | Tarragona | Gasolina | 0 |
Comunidad de Madrid | Tarragona | Diesel | 0 |
Comunidad de Madrid | Bilbao | Gasolina | 0 |
Comunidad de Madrid | Bilbao | Diesel | 0 |
Comunidad de Madrid | Coruña | Gasolina | 0 |
Comunidad de Madrid | Coruña | Diesel | 0 |
Cataluña | Cartagena | Gasolina | 0 |
Cataluña | Cartagena | Diesel | 0 |
Cataluña | Puertollano | Gasolina | 0 |
Cataluña | Puertollano | Diesel | 0 |
Cataluña | Bilbao | Gasolina | 0 |
Cataluña | Bilbao | Diesel | 0 |
Cataluña | Coruña | Gasolina | 0 |
Cataluña | Coruña | Diesel | 0 |
Castilla-La Mancha | Cartagena | Gasolina | 0 |
Castilla-La Mancha | Puertollano | Gasolina | 0 |
Castilla-La Mancha | Puertollano | Diesel | 0 |
Castilla-La Mancha | Tarragona | Gasolina | 0 |
Castilla-La Mancha | Tarragona | Diesel | 0 |
Castilla-La Mancha | Bilbao | Gasolina | 0 |
Castilla-La Mancha | Bilbao | Diesel | 0 |
Castilla y León | Cartagena | Gasolina | 0 |
Castilla y León | Cartagena | Diesel | 0 |
Castilla y León | Puertollano | Gasolina | 0 |
Castilla y León | Puertollano | Diesel | 0 |
Castilla y León | Tarragona | Gasolina | 0 |
Castilla y León | Tarragona | Diesel | 0 |
Castilla y León | Coruña | Gasolina | 0 |
Castilla y León | Coruña | Diesel | 0 |
Cantabria | Cartagena | Gasolina | 0 |
Cantabria | Cartagena | Diesel | 0 |
Cantabria | Puertollano | Gasolina | 0 |
Cantabria | Puertollano | Diesel | 0 |
Cantabria | Tarragona | Gasolina | 0 |
Cantabria | Tarragona | Diesel | 0 |
Cantabria | Coruña | Gasolina | 0 |
Cantabria | Coruña | Diesel | 0 |
Aragón | Cartagena | Gasolina | 0 |
Aragón | Cartagena | Diesel | 0 |
Aragón | Puertollano | Gasolina | 0 |
Aragón | Bilbao | Gasolina | 0 |
Aragón | Bilbao | Diesel | 0 |
Aragón | Coruña | Gasolina | 0 |
Aragón | Coruña | Diesel | 0 |
Andalucía | Cartagena | Gasolina | 0 |
Andalucía | Cartagena | Diesel | 0 |
Andalucía | Tarragona | Gasolina | 0 |
Andalucía | Tarragona | Diesel | 0 |
Andalucía | Bilbao | Gasolina | 0 |
Andalucía | Bilbao | Diesel | 0 |
Andalucía | Coruña | Gasolina | 0 |
Andalucía | Coruña | Diesel | 0 |
Tabla 4 – Vista de datos de la variable DemandaporRF
En la tabla 5 se puede apreciar de una forma más clara las refinerías que surten a cada comunidad autónoma. Debido al stock disponible y al coste del transporte se puede apreciar que a algunas comunidades autónomas los productos les vienen de diferentes refinerías.
Conclusiones
Este es un pequeño ejemplo de lo que se puede conseguir optimizando un problema de redes logísticas. Hay que tener en cuenta que una refinería de media produce entre 15 y 20 productos finales y se transportan por numerosos medios, de modo que podemos encontrarnos con cientos de variables, de restricciones y con millares de datos para procesar.
Por otro lado, tanto la demanda como la oferta pueden ser variables. En este ejercicio estamos analizando la distribución del stock en un día en concreto pero la realidad es que la tabla 5 cambie a diario.
Si analizamos la producción y la demanda, vemos que la producción actual es mayor que la demanda como indica la tabla 6.
Si la demanda se incrementa o la producción disminuye el problema nos indicaría que no hay solución posible, y en una situación real habría que buscar la manera de surtir a ciertas comunidades autónomas hasta tener de nuevo un balance positivo. En caso contrario, el sobrante se puede aprovechar para la venta en otros mercados o simplemente en procesos sucesivos ajustar la producción a la baja.
Enlaces y Bibliografía
[1] A. García Romero, M. Mena Jiménez, A. Soto Rebollo. Planificación y optimización de redes logísticas de transporte. Proyecto de sistemas informáticos [en línea]. Madrid, 2012. Disponible en: https://goo.gl/BaKLAo
[2] IBM ILOG CPLEX Optimization Studio
[3] J. J. Ruz. Tema7. Optimización de redes logísticas. Apuntes del profesor [en línea]. Madrid, 2015. Disponible en: https://goo.gl/Jafht4
[4] J. J. Ruz. Tema8. Optimización de procesos industriales. Apuntes del profesor [en línea]. Madrid, 2015. Disponible en: https://goo.gl/LvPPHP