在这篇文章中,我提供了一个编码示例,考虑一组容量无限的固定仓库,如何将一组客户分别分配到一个仓库。基本假设是没有固定成本,成本只取决于客户和仓库之间的欧几里得距离。此外,在这个问题中没有考虑前置时间要求或其他与服务水平相关的约束条件。
该算法非常简单,让人想起聚类算法。它循环浏览所有客户,并将每个客户分配到最近的仓库,考虑到欧氏距离和经纬度系统。下面我把这个算法定义为一个函数。
# 计算欧几里得距离的函数。
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)
}
# 用于将客户分配到仓库的功能。
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
}
为了测试,我先建立两套,分别是随机定位的客户和仓库。
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))
在客户位置数据框架的头部下方。
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
在仓库位置数据框架的头部下方
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
现在我把客户分配到仓库。
# 应用功能
results_df <- assignment_algorithm(customer_df,warehouse_df)
# 显示结果的标题
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
此外,我还在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)
仓库的位置如下:
ggplot(data = warehouse_df) + geom_point(mapping = aes(x=lat,y=long)) + xlim(-90,90) + ylim(-180,180)
在另一篇文章中,我展示了如何将仓库定位在质量中心,我在客户需求中心。
我还写过一些文章,介绍如何根据空间上的接近性,将一组客户划分为几个较小的集群。例如,这种方法可以用于在R中在每个客户的质量中心定位多个仓库。
专业领域为优化和仿真的工业工程师(R,Python,SQL,VBA)
Leave a Reply