天池最後一千米


title: "R Notebook"
author: "Harry Zhu"html

output: html_notebook

天池最後一千米算法

library(readr)
library(plyr)
library(dplyr)
Site = readr::read_csv("1.csv") %>% mutate(type = "Site") %>% rename(c("Site_id"='ID'))

Spot = readr::read_csv("2.csv") %>% mutate(type = "Spot") %>% rename(c("Spot_id" = "ID"))

Shop = readr::read_csv("3.csv") %>% mutate(type = "Shop") %>% rename(c("Shop_id" = "ID"))

library(tidyr)
Geo = rbind(Site,Shop,Spot)

E_Order = readr::read_csv("4.csv")
O2O_Order = readr::read_csv("5.csv")
Courier = readr::read_csv("6.csv")

#plot(Site$Lng,Site$Lat)
plot(Geo$Lng,Geo$Lat)
library(ggplot2)
ggplot(data=Geo, aes(x=Lng, y=Lat,color=type))+geom_point(0.1)

clipboard.png

# O2O訂單時間統計與分佈
O2O_ts = O2O_Order %>% tidyr::extract(col = Pickup_time,"Pickup_hour") %>% tidyr::extract(col = Delivery_time,"Delivery_hour")

#  這裏能夠看到11-13點和17-18點是一個O2O下單高峯時段

plot(table(O2O_ts$Pickup_hour))

Pickup_hour

# 而配送時間則稍有滯後,在15-點到18點爲低谷期
plot(table(O2O_ts$Delivery_hour))

Delivery_hour

total_Order = rbind(E_Order,O2O_Order)

total_Spot_rank = total_Order %>% group_by(Spot_id) %>% summarise(Order_num = sum(Num)) %>% arrange(Order_num)
# 觀察訂單合併分佈狀況 # 配送點的總訂單狀況
plot(table(total_Spot_rank$Order_num))
# 咱們觀察到,絕大多數配送點(9202)都是符合合單配送的,只有12單是不知足合單配送,須要單獨配送。

clipboard.png

# 在早上8點-10點集中配送電商訂單,快遞員在11-13點集中配送O2O訂單,在14-17點混合配送電商和O2O訂單,17-19點集中配送O2O訂單,19點-20點混合配送電商和O2O訂單
時間段 包裹類型 持續時長 解決順序
8-11點 電商 2小時 5
11-13點 O2O 2小時 1
13-17點 混合 4小時 4
17-19點 O2O 2小時 2
19-20點 混合 1小時 3

在實際商業場景中,O2O配送是賺錢的,並且客單價不低,無論是自營仍是加盟,上海O2O一次配送能夠有6-10元左右的提成。而電商配送須要區分是自營仍是加盟,若是是加盟配送在送件上是不賺錢的,在取件上才賺錢。因此,電商快遞員們其實天天都是很是辛苦的,上午須要集中取件配送,下午通常是集中收件,到是O2O配送在非高峯時段能夠解放出配送的生產力。spa

O2O實際的配送狀況是,對於加盟配送員(默認3千米範圍內)在找到取餐地點可能就會花費10分鐘,在中間行駛還會花費10分鐘,最後10分鐘還要花在找到送餐地點。因此,O2O配送對於配送員對地理狀況的瞭解有比較高的要求,熟悉地理狀況將大大縮短配送時長。設計

O2O在用餐高峯時期的時間約束是很是緊急的,對於送餐員是分秒必爭,這一點和電商配送是有顯著差異的,因此咱們在算法設計上能夠從這個邊界條件入手(OR的基本原理:最優解老是發生在邊界條件上)。3d

O2O_Pickup_time = ldply(strsplit(O2O_Order$Pickup_time, ":"), rbind) %>% plyr::rename(c("1"='P_hour',"2"="P_minute"))

O2O_Delivery_time = ldply(strsplit(O2O_Order$Delivery_time, ":"), rbind) %>% plyr::rename(c("1"='D_hour',"2"="D_minute"))

O2O_Order_ts <- O2O_Order %>% cbind(O2O_Pickup_time,O2O_Delivery_time) %>% select(-Pickup_time,-Delivery_time) %>% tbl_df()

# 首先篩選出高峯訂單
rush_Order_1 <- O2O_Order_ts %>% dplyr::filter(P_hour == c(11,12))
library(DT)
DT::datatable(rush_Order_1 %>% arrange(Spot_id,Source_id))

clipboard.png

# 咱們觀察到有一些配送點會從多家店鋪分時下單(腦補一個公司你們各自訂餐的場景)
# 有的場景是一個店家向多個配送點配送。
# 這樣就有了一取多送和多取一送的兩個基本問題。
# 根據題目寫了一個距離計算公式
distLastMile <- function(lat1,lat2,lng1,lng2){
  # parameter type check
  if(class(lat1) != "numeric" ||class(lat2) != "numeric" ||class(lng1) != "numeric" ||class(lng2) != "numeric" ){
    stop("parameter must be numeric")
  }
  # reference https://img.alicdn.com/tps/TB1CiDVKXXXXXcpXFXXXXXXXXXX-866-255.png
  diff_lat = (lat1 - lat2)/2
  diff_lng = (lng1 - lng2)/2
  radius = 6378137
  temp = (sin((pi * diff_lat )/180))^2 + cos((pi * lat1)/180) * cos((pi * lat2)/180)*(sin((pi * diff_lng )/180))^2
  result = 2 * radius * asin (sqrt(temp))
  return(result)
}
# 以題中給定15km/h的移動速度,估算

# > Geo[Geo$ID=="S062",]
# # A tibble: 1 x 4
#      ID     Lng      Lat  type
#   <chr>   <dbl>    <dbl> <chr>
# 1  S062 121.217 31.04957  Shop
# > Geo[Geo$ID=="B1958",]
# # A tibble: 1 x 4
#      ID     Lng      Lat  type
#   <chr>   <dbl>    <dbl> <chr>
# 1 B1958 121.217 31.04973  Spot

# distance = distLastMile(lat1=31.04973,lat2=31.04957,lng1=121.217,lng2=121.217)
# [1] 17.81112 
#  distance * 4
# [1] 71.24448

這裏計算出來的結果是至少71分鐘左右的配送時長,17km左右的配送距離。因爲不太肯定O2O的具體業務,因此說不敢對這個配送時長的合理性作判斷。code

rush_info_1[rush_info_1$Order_id == "E0036",]
# A tibble: 1 x 11
#  Order_id Spot_id Source_id   Num P_hour P_minute D_hour D_minute     Lng      Lat  type
#     <chr>   <chr>     <chr> <int> <fctr>   <fctr> <fctr>   <fctr>   <dbl>    <dbl> <chr>
#1    E0036   B1958      S062     3     12       14     13       44 121.217 31.04973  Spot

# 配送時長最長可爲 90分鐘,看來就是怎麼利用之間的 20分鐘的時間來增長配送量。

接下來,咱們繼續分解任務,將O2O配送分爲三種類型cdn

  1. 一對多:同一家店鋪取,順序配送到多個目的地(旺鋪型)htm

  2. 多對一:多家店鋪順序取件,一次配送到目的地(大客戶型)blog

  3. 其餘ip

# 一對多的情形
# reference https://www.youtube.com/watch?v=A1wsIFDKqBk
相關文章
相關標籤/搜索