阿里天池大赛:最后一公里急速配送

论坛 期权论坛     
选择匿名的用户   2021-5-23 02:01   206   0
<div class="article fmt article__content">
<h2>前言</h2>
<p>最近公司组织了一场大咖秀,有位讲师建议我们没事多参加阿里的天池大赛,说是对提高自己很有帮助。于是想起自己几天前看到的FinanceR专栏的<a href="https://segmentfault.com/a/1190000006036420">天池最后一公里</a>,便紧随偶像步伐,注册并下载了一份数据,凑个热闹。详情请点击<a href="https://tianchi.shuju.aliyun.com/competition/information.htm?spm&#61;5176.100067.5678.2.mJKvo4&amp;raceId&#61;231581">赛题介绍</a></p>
<p>此文为截图版,需要js交互版的原文请点击<a href="http://danzhuibing.github.io/R_tianchi_logistics.html">这里</a></p>
<h2>简单分析</h2>
<p>数据有三种类型的节点。第一类是Site,电商订单发货节点。第二类是Shop,O2O订单发货节点。第三类是Spot,消费者收获节点。电商订单的要求比较松,只需在当天晚上8点前配送完毕即可。O2O订单比较着急,必须在指定的时刻前去Shop取货,并在指定的时刻去Spot送货。</p>
<p>首先,我们将电商订单的情况打到地图上看一下。</p>
<pre class="blockcode"><code>library(readr)
library(plyr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(plotly)
library(lubridate)
library(leaflet)
library(sp)
library(RColorBrewer)
library(jsonlite)
library(splitstackshape)
library(stringr)
library(rlist)

# 辅助函数
points2spline &lt;- function(df, x_field, y_field, id_field){
  data &lt;- as.matrix(df[,c(x_field, y_field)])
  id &#61; df[1, id_field]
  Lines(list(Line(data)), ID&#61;id)
}  

# 探索Site与Spot的空间关系
df.site &lt;- read_csv(&#34;1.csv&#34;)
df.spot &lt;-  read_csv(&#34;2.csv&#34;)
df.e.order &lt;- read_csv(&#34;4.csv&#34;)

df.site.spot &lt;- df.e.order %&gt;%
  inner_join(df.site, by&#61;c(&#34;Site_id&#34;)) %&gt;%
  inner_join(df.spot, by&#61;c(&#34;Spot_id&#34;)) %&gt;%
  unite(Point_x, ends_with(&#34;x&#34;)) %&gt;%
  unite(Point_y, ends_with(&#34;y&#34;)) %&gt;%
  gather(point, location, Point_x, Point_y) %&gt;%
  separate(location, c(&#34;Lng&#34;, &#34;Lat&#34;), sep&#61;&#34;_&#34;, convert&#61;TRUE) %&gt;%
  unite(Line_id, Site_id, Spot_id, remove&#61;FALSE)

df.site &lt;- df.site %&gt;%
  inner_join(df.site.spot %&gt;%
               group_by(Site_id) %&gt;%
               dplyr::summarise(order_cnt&#61;sum(Num)),
             by&#61;c(&#34;Site_id&#34;))
  
ls.site.spot &lt;- split(df.site.spot, df.site.spot[, c(&#34;Line_id&#34;)])
names(ls.site.spot) &lt;- NULL
sl.site.spot &lt;- SpatialLines(llply(ls.site.spot, points2spline, &#34;Lng&#34;, &#34;Lat&#34;, &#34;Line_id&#34;))
m &lt;- leaflet() %&gt;%
  addTiles(
    &#39;http://webrd02.is.autonavi.com/appmaptile?lang&#61;zh_cn&amp;size&#61;1&amp;scale&#61;1&amp;style&#61;8&amp;x&#61;{x}&amp;y&#61;{y}&amp;z&#61;{z}&#39;,
    tileOptions(tileSize&#61;256, minZoom&#61;9, maxZoom&#61;17)
  ) %&gt;%
  addPolylines(data&#61;sl.site.spot, weight&#61;2, color&#61;&#34;#377EB8&#34;) %&gt;%
  addCircleMarkers(lng&#61;~Lng, lat&#61;~Lat, radius&#61;~order_cnt/1000, data&#61;df.site, stroke&#61;FALSE, fill&#61;TRUE, fillColor&#61;&#34;#E41A1C&#34;, fillOpacity&#61;0.5, popup&#61;~paste0(&#34;Order Num: &#34;, order_cnt)) %&gt;%
  fitBounds(sl.site.spot&#64;bbox[&#34;x&#34;, &#34;min&#34;],sl.site.spot&#64;bbox[&#34;y&#34;, &#34;min&#34;], sl.site.spot&#64;bbox[&#34;x&#34;, &#34;max&#34;], sl.site.spot&#64;bbox[&#34;y&#34;, &#34;max&#34;])
m</code></pre>
<p><span class="img-wrap"><img alt="clipboard.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-51644129b90f5f65e7528b8d70e528c9" title="clipboard.png"></span></p>
<p>图中红色的圆圈就是每个Site,半径越长表明出货量越大。蓝色的线表示这个Site与它负责的电商订单的Spot的连线。可以看出Site和Spot之间是一一对应的关系,不存在交叉,所以如果只考虑电商订单,这就是一个比较简单的VRP问题,可以分而治之,每个Site单独规划。</p>
<p>但是呢,我们还有一堆O2O订单要一起配送,这就让问题的复杂度骤然提升了难度。我们先来看一下O2O订单的空间分布。</p>
<pre class="blockcode"><code>df.shop &lt;- read_csv(&#34;3.csv&#34;)
df.o2o.order &lt;- read_csv(&#34;5.csv&#34;)

df.shop.spot &lt;- df.o2o.order %&gt;%
  inner_join(df.shop, by&#61;c(&#34;Shop_id&#34;)) %&gt;%
  inner_join(df.spot, by&#61;c(&#34;Spot_id&#34;)) %&gt;%
  unite(Point_x, ends_with(&#34;x&#34;)) %&gt;%
  unite(Point_y, ends_with(&#34;y&#34;)) %&gt;%
  gather(point, location, Point_x, Point_y) %&gt;%
  separate(location, c(&#34;Lng&#34;, &#34;Lat&#34;), sep&#61;&#34;_&#34;, convert&#61;TRUE) %&gt;%
  unite(Line_id, Shop_id, Spot_id, remove&#61;FALSE)

ls.shop.spot &lt;- split(df.shop.spot, df.shop.spot[, c(&#34;Line_id&#34;)])
names(ls.shop.spot) &lt;- NULL
sl.shop.spot &lt;- SpatialLines(llply(ls.shop.spot, points2spline, &#34;Lng&#34;, &#34;Lat&#34;, &#34;Line_id&#34;))

df.shop &lt;- df.shop %&gt;%
  inner_join(df.shop.spot %&gt;%
               group_by(Shop_id) %&gt;%
               dplyr::summarise(order_cnt&#61;sum(Num)),
             by&#61;c(&#34;Shop_id&#34;))

m &lt;- leaflet() %&gt;%
  addTiles(
    &#39;http://webrd02.is.autonavi.com/appmaptile?lang&#61;zh_cn&amp;size&#61;1&amp;scale&#61;1&amp;style&#61;8&amp;x&#61;{x}&
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP