PROBLEMA

Librerías

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.2
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.0
## ✔ readr     2.1.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(pillar)
## 
## Attaching package: 'pillar'
## 
## The following object is masked from 'package:dplyr':
## 
##     dim_desc
library(psych)
## 
## Attaching package: 'psych'
## 
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(skimr)
library(readr)
library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
library(corrplot)
## corrplot 0.92 loaded
library(reshape2)
## 
## Attaching package: 'reshape2'
## 
## The following object is masked from 'package:tidyr':
## 
##     smiths
library(gmodels)
library(mice)
## 
## Attaching package: 'mice'
## 
## The following object is masked from 'package:pillar':
## 
##     squeeze
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following objects are masked from 'package:base':
## 
##     cbind, rbind
library(VIM)
## Loading required package: colorspace
## Loading required package: grid
## VIM is ready to use.
## 
## Suggestions and bug-reports can be submitted at: https://github.com/statistikat/VIM/issues
## 
## Attaching package: 'VIM'
## 
## The following object is masked from 'package:datasets':
## 
##     sleep
library(scales)
## 
## Attaching package: 'scales'
## 
## The following objects are masked from 'package:psych':
## 
##     alpha, rescale
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     combine
library(quantmod)
## Loading required package: xts
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## 
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## 
## ######################### Warning from 'xts' package ##########################
## #                                                                             #
## # The dplyr lag() function breaks how base R's lag() function is supposed to  #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or       #
## # source() into this session won't work correctly.                            #
## #                                                                             #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop           #
## # dplyr from breaking base R's lag() function.                                #
## #                                                                             #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning.  #
## #                                                                             #
## ###############################################################################
## 
## Attaching package: 'xts'
## 
## The following objects are masked from 'package:dplyr':
## 
##     first, last
## 
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(tseries)
library(fImport)
## Loading required package: timeDate
## 
## Attaching package: 'timeDate'
## 
## The following object is masked from 'package:pillar':
## 
##     align
## 
## Loading required package: timeSeries
## 
## Attaching package: 'timeSeries'
## 
## The following object is masked from 'package:zoo':
## 
##     time<-
## 
## The following object is masked from 'package:psych':
## 
##     outlier
library(seriation)
## Registered S3 methods overwritten by 'registry':
##   method               from 
##   print.registry_field proxy
##   print.registry_entry proxy
library(forecast)
library(gvlma)
library(olsrr)
## 
## Attaching package: 'olsrr'
## 
## The following object is masked from 'package:datasets':
## 
##     rivers
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:psych':
## 
##     logit
## 
## The following object is masked from 'package:purrr':
## 
##     some
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
library(MASS)
## 
## Attaching package: 'MASS'
## 
## The following object is masked from 'package:olsrr':
## 
##     cement
## 
## The following object is masked from 'package:dplyr':
## 
##     select
library(knitr)
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.3.2
## 
## Attaching package: 'kableExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     group_rows

EDA — EXPLORATORY DATA ANALYSIS

Lectura del dataset y realización de datasets necesarios

btc = read.csv("/Users/ximenaverastegui/Desktop/envios.csv") #envíos 

# exclusivo: paquetes que van de cada planta a cada CeDis
destino <- subset(btc, select = -c(Peso..Ton., EarliestDeliveryTime, LatestDeliveryTime, Producto))

# exclusivo: tiempos de tránsito de cada planta a cada CeDis en vehículo y ferroviario (horas)
transito = read.csv("/Users/ximenaverastegui/Desktop/transito.csv")

ubi_plantas <- c("Pta_Zapotiltic","Pta_Monterrey","Pta_Hidalgo","Pta_Norte","Pta_Guadalajara","Pta_Edo_Mex","Pta_Queretaro")

ubi_cedis <- c("BNPLRO0001","CLCOAA0035","BNENDA0001","CLARIA0001","CIOCES0001","BNMELI0001","CLCUOC0001","BSCAOS0001","BNENDA2658","BNTINA0001","CLCOMA0001","CLCOAN0001","AGAGES0001","CLCUOC0018","CLCOMA0077")

capacidad_descarga <- data.frame(
  Equipo = c("Furgon", "Goldona", "Tolva", "Full", "Trailer"),
  Capacidad.ton = c(60,90,120,30,60),
  TiempoDescarga.hr = c(2,3,4,1,2)
)

tarifas_completo = read.csv("/Users/ximenaverastegui/Desktop/tarifas.csv")
tarifas_completo$Costo.por.Kilometro <- as.numeric(gsub("\\$", "", tarifas_completo$Costo.por.Kilometro))
tarifas <- subset(tarifas_completo, select = -c(Servicio,Destino))

total_proveedor <- data.frame(
  Proveedor = c("FERRO01",
"FERRO02",
"FERRO03",
"EDO_FULL_CMX_FV_1",
"EDO_TRAILER_CMX_FV_1",
"GDL_FULL_CMX_FV_1",
"GDL_TRAILER_CMX_FV_1",
"HID_FULL_CMX_FV_1",
"HID_TRAILER_CMX_FV_1",
"LOC_FULL_CMX_FV_1",
"LOC_TRAILER_CMX_FV_1",
"MEX_FULL_CMX_FV_1",
"MTY_FULL_CMX_FV_1",
"MTY_TRAILER_CMX_FV_1",
"NOR_FULL_CMX_FV_1",
"NOR_TRAILER_CMX_FV_1",
"QUE_FULL_CMX_FV_1",
"QUE_TRAILER_CMX_FV_1",
"REY_FULL_CMX_FV_1",
"REY_TRAILER_CMX_FV_1",
"ZOP_FULL_CMX_FV_1",
"ZOP_TRAILER_CMX_FV_1"),
Total = c(84,84,84,30,15,30,15,30,15,30,15,30,30,15,30,15,30,15,30,15,30,15))

total_equipo <- data.frame(
  Equipo = c("Furgon","Gondola","Tolva","Full","Trailer"),
  Total = c(84, 84, 84, 300,    135)
)

disponibilidadTipo <- read.csv("/Users/ximenaverastegui/Desktop/disponibilidadTipo.csv")
disponibilidadTipo[is.na(disponibilidadTipo)] <- 0

Bar Charts — visualización rápida de paquetes de planta a CeDis

# lista única de plantas
plantas_unicas <- unique(btc$Origen)

# creación de gráficos de barras para cada planta
for (planta in plantas_unicas) {
  datos_planta <- btc[btc$Origen == planta, ]
  
  paquetes_por_destino <- table(datos_planta$Destino)
  paquetes_por_destino
  
  #barplot(paquetes_por_destino,main=planta,xlab = "Centro de Distribución",ylab = "Cantidad de Paquetes")
  
  barplot(paquetes_por_destino, main = planta, xlab = "Centro de Distribución", ylab = "Cantidad de Paquetes", ylim=c(0, max(paquetes_por_destino) + 1))

  text(x = barplot(paquetes_por_destino, plot = FALSE), y = paquetes_por_destino + 0.1, label = paquetes_por_destino, cex = 0.8, col = "black")

  # Mostrar el nombre de cada centro de distribución sobre cada barra
  text(x = barplot(paquetes_por_destino, plot = FALSE), y = -0.5, label = names(paquetes_por_destino), cex = 0.8, srt = 45, pos = 2, xpd = TRUE)

}

Tabla PAQUETES

# TABLA PAQUETES
# Instalar y cargar el paquete knitr si no está instalado
if (!requireNamespace("knitr", quietly = TRUE)) {
  install.packages("knitr")
}
library(knitr)
# Crear una tabla con los datos
plantas_unicas <- unique(btc$Origen)

tabla_datos <- matrix(0, nrow = length(plantas_unicas) + 1, ncol = length(unique(btc$Destino)) + 1)
rownames(tabla_datos) <- c(plantas_unicas, "Total")
colnames(tabla_datos) <- c(unique(btc$Destino), "Total")

# Llenar la tabla con la cantidad de paquetes entregados
for (planta in plantas_unicas) {
  datos_planta <- btc[btc$Origen == planta, ]
  paquetes_por_destino <- table(datos_planta$Destino)
  tabla_datos[planta, names(paquetes_por_destino)] <- paquetes_por_destino
  tabla_datos[planta, "Total"] <- sum(paquetes_por_destino)  # Calcular total de paquetes por planta
}

# Calcular el total de paquetes por centro de distribución y agregarlo como una fila adicional
for (i in 1:ncol(tabla_datos)) {
  tabla_datos[length(plantas_unicas) + 1, i] <- sum(tabla_datos[1:length(plantas_unicas), i])  # Calcular total de paquetes por centro de distribución
}

# Mostrar la tabla con formato y estilos CSS
kable(tabla_datos, format = "html") %>%
  kable_styling("striped", full_width = FALSE) %>%
  column_spec(1, bold = TRUE) %>%
  add_header_above(c(" " = 1, "Centro de Distribución" = ncol(tabla_datos))) %>%
  add_footnote("Nota: Los valores representan la cantidad de paquetes entregados por planta y centro de distribución.")
Centro de Distribución
BNPLRO0001 CLCOAA0035 BNENDA0001 CLARIA0001 CIOCES0001 BNMELI0001 CLCUOC0001 BSCAOS0001 BNENDA2658 BNTINA0001 CLCOMA0001 CLCOAN0001 AGAGES0001 CLCUOC0018 CLCOMA0077 Total
Pta_Monterrey 15 14 12 8 3 6 15 5 4 11 5 12 6 14 6 136
Pta_Zapotiltic 13 7 7 7 7 10 10 7 11 8 14 9 11 15 11 147
Pta_Hidalgo 11 10 11 9 6 5 9 11 10 6 14 11 6 13 5 137
Pta_Norte 11 10 10 9 9 12 7 9 9 15 14 17 12 7 8 159
Pta_Guadalajara 11 9 14 8 6 9 11 10 10 8 6 9 9 8 5 133
Pta_Edo_Mex 12 6 8 11 16 6 14 12 13 15 5 7 12 12 8 157
Pta_Queretaro 4 5 10 10 11 6 3 14 5 7 12 13 11 6 13 130
Total 77 61 72 62 58 54 69 68 62 70 70 78 67 75 56 999
a Nota: Los valores representan la cantidad de paquetes entregados por planta y centro de distribución.
#install.packages("openxlsx")
#library(openxlsx)
#datos <- as.data.frame.matrix(tabla_datos)
#write.xlsx(datos, "paquetes.xlsx")

Tabla TONELADAS

# TABLA TONELADAS
# Crear una tabla con los datos
plantas_unicas <- unique(btc$Origen)

tabla_datos_ton <- matrix(0, nrow = length(plantas_unicas) + 1, ncol = length(unique(btc$Destino)) + 1)
rownames(tabla_datos_ton) <- c(plantas_unicas, "Total")
colnames(tabla_datos_ton) <- c(unique(btc$Destino), "Total")

# Llenar la tabla con la cantidad de paquetes entregados y convertir a toneladas
for (planta in plantas_unicas) {
  datos_planta_ton <- btc[btc$Origen == planta, ]
  paquetes_por_destino_ton <- table(datos_planta_ton$Destino)
  toneladas_por_destino <- paquetes_por_destino_ton * 30  # Convertir paquetes a toneladas
  tabla_datos_ton[planta, names(paquetes_por_destino_ton)] <- toneladas_por_destino
  tabla_datos_ton[planta, "Total"] <- sum(toneladas_por_destino)  # Calcular total de toneladas por planta
}

# Calcular el total de toneladas por centro de distribución y agregarlo como un renglón adicional
for (i in 1:ncol(tabla_datos_ton)) {
  tabla_datos_ton["Total", i] <- sum(tabla_datos_ton[1:length(plantas_unicas), i])
}

# Mostrar la tabla con formato y estilos CSS
kable(tabla_datos_ton, format = "html") %>%
  kable_styling("striped", full_width = FALSE) %>%
  column_spec(1, bold = TRUE) %>%
  add_header_above(c(" " = 1, "Centro de Distribución" = ncol(tabla_datos_ton))) %>%
  add_footnote("Nota: Los valores representan la cantidad de toneladas entregadas por planta y centro de distribución.")
Centro de Distribución
BNPLRO0001 CLCOAA0035 BNENDA0001 CLARIA0001 CIOCES0001 BNMELI0001 CLCUOC0001 BSCAOS0001 BNENDA2658 BNTINA0001 CLCOMA0001 CLCOAN0001 AGAGES0001 CLCUOC0018 CLCOMA0077 Total
Pta_Monterrey 450 420 360 240 90 180 450 150 120 330 150 360 180 420 180 4080
Pta_Zapotiltic 390 210 210 210 210 300 300 210 330 240 420 270 330 450 330 4410
Pta_Hidalgo 330 300 330 270 180 150 270 330 300 180 420 330 180 390 150 4110
Pta_Norte 330 300 300 270 270 360 210 270 270 450 420 510 360 210 240 4770
Pta_Guadalajara 330 270 420 240 180 270 330 300 300 240 180 270 270 240 150 3990
Pta_Edo_Mex 360 180 240 330 480 180 420 360 390 450 150 210 360 360 240 4710
Pta_Queretaro 120 150 300 300 330 180 90 420 150 210 360 390 330 180 390 3900
Total 2310 1830 2160 1860 1740 1620 2070 2040 1860 2100 2100 2340 2010 2250 1680 29970
a Nota: Los valores representan la cantidad de toneladas entregadas por planta y centro de distribución.
#datos_ton <- as.data.frame.matrix(tabla_datos_ton)
#write.xlsx(datos_ton, "toneladas.xlsx")

OPTIMIZACIÓN CICLOS

x <- c(60,90,120,60,90,120,60,90,120,60,90,120)

# Generar las combinaciones
combinations_list <- unlist(lapply(0:length(x), function(m) {combn(x, m = m, simplify = FALSE)}), recursive = FALSE)

# Verificar si la longitud de cada subelemento es igual a 1
#is_length_1 <- sapply(combinations_list, function(comb) length(comb) == 1)
is_length_5 <- sapply(combinations_list, function(comb) length(comb) == 5)
is_length_6 <- sapply(combinations_list, function(comb) length(comb) == 6)
is_length_7 <- sapply(combinations_list, function(comb) length(comb) == 7)
is_length_8 <- sapply(combinations_list, function(comb) length(comb) == 8)
is_length_9 <- sapply(combinations_list, function(comb) length(comb) == 9)
is_length_10 <- sapply(combinations_list, function(comb) length(comb) == 10)

# Imprimir los subelementos con longitud igual a 1
#combinations_list[is_length_1]
#combinations_list[is_length_5]
#combinations_list[is_length_6]
#combinations_list[is_length_7]
#combinations_list[is_length_8]
#combinations_list[is_length_9]
#combinations_list[is_length_10]


# me interesa length 5, 6, 7, 8, 9, 10. Hacer un ciclo for con estos y luego multipllicar el costo del tipo de vagon (con restricción si 60 = costoFurgon, 90 = costoGondola, 120 = costoTolva) * KM de la Planta al Cedis (recorro la matriz y veo que coincida con qué??? ). Y luego ver que la suma de este de el número del envío y si no, se mete en otro ciclo para hacer más lapsos y ver con qué otra combinación concuerda.