Problema de asignación de almacén: asignación de clientes al almacén más cercano (usando R)

En esta publicación proporciono un ejemplo de codificación de cómo se puede asignar un grupo de clientes a un almacén cada uno, considerando un conjunto de almacenes fijos con capacidad ilimitada. El supuesto subyacente es que no hay costos fijos y que los costos solo dependen de la distancia euclidiana entre el cliente y el almacén. Además, en este problema no se consideran requisitos de tiempo de entrega ni otras limitaciones relacionadas con el nivel de servicio.

El algoritmo es muy simple y recuerda a los algoritmos de agrupamiento. Recorre todos los clientes y asigna a cada cliente el almacén más cercano, considerando la distancia euclidiana y el sistema de latitud-longitud. A continuación defino este algoritmo como una función:

# función para calcular distancias euclidianas
euclidean_distance <- function(vc,df){
  sqrt((as.numeric(rep(vc[1],times=nrow(df)))-df[,1])^2+(as.numeric(rep(vc[2],times=nrow(df)))-df[,2])^2)
}

# función para asignar clientes a almacenes
assignment_algorithm <- function(customers,warehouses){
  return_df <- as.data.frame(matrix(nrow=nrow(customers),ncol=3))
  colnames(return_df)<-c("lat","long","warehouses")
  for(i in 1:nrow(customers)){
    return_df[i,] <- c(customers[i,1],customers[i,2],which.min(euclidean_distance(customers[i,],warehouses)))
  }
  return_df
}

Para probar, primero construyo dos conjuntos, con clientes y almacenes ubicados aleatoriamente, respectivamente.

customer_df <- as.data.frame(matrix(nrow=1000,ncol=2))
colnames(customer_df) <- c("lat","long")
warehouse_df <- as.data.frame(matrix(nrow=4,ncol=2))
colnames(warehouse_df) <- c("lat","long")

customer_df[,c(1,2)] <- cbind(runif(n=1000,min=-90,max=90),runif(n=1000,min=-180,max=180))
warehouse_df[,c(1,2)] <- cbind(runif(n=4,min=-90,max=90),runif(n=4,min=-180,max=180))

Debajo del encabezado del marco de datos de ubicación del cliente:

head(customer_df)
##         lat      long
## 1 -35.42042 -33.68156
## 2 -50.63025 -64.52526
## 3  43.71663 -36.22302
## 4 -53.30511 135.56315
## 5 -46.32125  84.83210
## 6  83.85849 -60.70374

Debajo del encabezado del marco de datos de ubicación de una casa:

head(warehouse_df)
##          lat      long
## 1 -41.007642  118.5673
## 2  81.968627  116.1495
## 3  11.971601  103.5034
## 4  -6.619224 -103.6206

Ahora asigno clientes a los almacenes:

# aplicar función
results_df <- assignment_algorithm(customer_df,warehouse_df)
# mostrar el encabezado del resultado
head(results_df)
##         lat      long warehouses
## 1 -35.42042 -33.68156          4
## 2 -50.63025 -64.52526          4
## 3  43.71663 -36.22302          4
## 4 -53.30511 135.56315          1
## 5 -46.32125  84.83210          1
## 6  83.85849 -60.70374          4

Además, visualizo los resultados en ggplot2:

library(ggplot2)
ggplot(data = results_df) + 
  geom_point(mapping = aes(x=lat,y=long,color=as.character(warehouses))) +
  scale_color_manual(values=c("darkblue","darkgreen","darkred","yellow")) +
  xlim(-90,90) + ylim(-180,180)

Los almacenes se ubican de la siguiente manera:

ggplot(data = warehouse_df) + geom_point(mapping = aes(x=lat,y=long)) + xlim(-90,90) + ylim(-180,180)

En otra publicación muestro cómo ubicar un almacén en el centro de masa, yo en el centro de la demanda del cliente: Problema de un solo almacén – Ubicación del almacén en el centro de masa (cálculo del centro de masa en R) También he escrito publicaciones sobre cómo dividir un grupo de clientes en varios grupos más pequeños, según la proximidad espacial. Este enfoque puede, por ejemplo, utilizarse para ubicar varios almacenes en cada uno de sus centros de masa en R.

Leave a Reply

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Close

Meta