1 内容介绍

前瞻产业研究院发布的《中国在线外卖商业模式与投资战略规划分析报告》统计数据显示,2015-2018年中国在线外卖收入年均增速约为117.5%,是传统餐饮业的12.1倍,我国在线外卖收入从2015的458亿元增长至2018年的4712亿元左右,占全国餐饮业收入比重从1.4%提高到10.6%。

随着外卖逐渐普及,问题也随之涌现。作为主要消费群体的白领阶层和学生对服务体验的要求较高,而配送慢是他们对外卖服务最为直观的感受。从商家的角度看,外卖配送也是最棘手的问题。

现如今主要存在三种配送模式,各配送模式提供方不同、服务人群与范围不同,各自的作用也不同。自运营配送模式:商家在接到顾客订单后,由商家自身员工或是商家招聘的兼职人员负责外卖的配送,外卖平台只负责线上整合商家信息。合作加盟配送模式:由于存在商家的自营外卖配送模式不能满足顾客需求的情况,外卖平台则会根据具体情况与第三方物流配送团队进行合作加盟,为这些商家提供物流支持。众包物流配送模式:每一个自愿兼职且通过考核认证的个人都可以成为外卖配送员,也就是现在的“骑手”。这种模式通过利用社会的零散人力能够有效的整合资源,使得人力资源成本大大降低,即使在送餐高峰期,也有充足的人力满足外卖的配送,外卖平台也不必增加额外的运营成本。但外卖平台对这一模式的配送环节无法进行实施监控,骑手会因个人原因导致配送出错、配送不及时、服务质量差等一系列问题。

本文以众包物流配送模式作为研究对象,基于物流路径规划提出以遗传算法提高配送速度的配送方案,借以提高用户用餐体验,实现商家与用户的双赢。

1.2国内外现状分析

1.2.1国外现状分析

以国外外卖020标杆的Grub Hub为例,Grub Hub在模式上两头兼顾,在发展客户服务的同时也为商家提供优质可靠的服务。面向用户的终端,Grub Hub实现了标准化服务,规范有序忙而不乱,并提供TrackYourGrub,使得用户能够在终端直观监测外卖的配送情况,这一点国内外卖平台设计中值得借鉴。面向商家,Grub Hub商家系统提供商户统计、安排订单等基础服务,还提供了对订单数、利润率、重复订餐率等数据进行综合分析为商家提出相应合理的调整建议功能,这吸引了美国市场份额超过6成的个体餐厅加入Grub Hub。

1.2.2国内现状分析

对于国内外卖市场而言,小餐饮商家和品牌餐饮几乎囊括整个外卖市场,而两者面向消费者的意愿存在较大差异,使得比较成熟的轻模式平台都在向轻重结合的混合模式转变。大部分商家会选择加入多家第三方外卖平台,但问题出现了,不同平台有不同的配送解决方案,甚至有的第三方平台并未提供配送解决方案,这样从一台打印机中出来的订单得按照平台不同区分开来给不同平台配送团队,而未提供配送解决方案平台的订单配送还要自己消化,繁琐至极,极易出乱。

总的来说,在配送方面,较为成熟的第三方O2O外卖平台都在发展自己的配送业务,但由于存在内部竞争关系使得对于整个外卖配送环节的高度整合难以实现。此外,我国消费者普遍付费意识比较差,消费者对有偿配送服务收取佣金的接受程度很低,使得商家在配送环节的花费的成本居高不下。开发一套整合配送服务增加客户体验降低配送成本的解决方案显得尤为重要。

国内王荃菲[1]重点研究了针对城市复杂路况的外卖配送路径的优化问题。楚尚轩[2]研究了外卖和快递共同配送的问题。沙小卜[3]对外卖配送网络进行了研究。

本文将基于遗传算法,针对“众包”配送模式提出一种路径优化方法,并且使得各外卖平台配送方案不统一问题得到解决。

2问题描述和数学模型

2.1模型假设

外卖配送的实际运行是一个复杂的过程,受诸多因素影响,为了建立调度模型,本文做如”下假设。

(1)外卖配送更多的是服务特殊群体,所以本文认为外卖配送是一种预约型配送,即在进行调度安排前,已经获取了所有顾客的地理信息。

(2)在实际运行中,顾客的出行分布具有很强的时空特征,但本文更注重方法论的介绍。所以,假设服务区域内的顾客地理位置分布在时间和空间上都服从均匀分布。

(3)外卖配送车辆的调度与路网条件息息相关,为了简化模型以及便于说明设计思路,忽略路网对调度的影响。Quadrifogli等已经证明“对角”路径能够反映车辆真实的运行情况。本文假设车辆按“对角"路径运行,即车辆只能沿水平或垂直方向运行。

(4)可配送车辆常用于低密度区域,顾客购买总量小,所以为了简化模型不考虑车辆的容量约束。

2.2模型建立

外卖配送的车辆调度是在确定总的配送计划之后,根据顾客的位置信息,解决“每个车次服务哪些顾客,怎么配送”的问题。外卖配送从运营者和顾客角度出发建立双层规划模型,运营者希望在投入下能够服务更多的顾客,顾客则希望送达的时间越短越好。

假如有一个取餐地点以及送餐地点n,配送车辆每经过一段距离的配送成本c,取餐地点和送餐地点距离d;能够参与配送的车辆数量为m,把表示取餐地点的这个点当作0點,送餐地点当作1,2,…,n,定义变量为:

在表示目标函数的公式(2)中,其结果代表外卖配送车辆从起始点到最终的目的地所花销的总成本。利用公式(3),公式(4)和公式(5)让不同地点的顾客至少有一辆车前往配送,公式(6)是指外卖配送车辆在配送的过程中总的花费时间小于限制时间。

3遗传算法设计

遗传算法是一种解决最优化问题,得出最优解的方法。该算法是一种高度并行、随即和自适应优化算法,是J.Holland教授提出的。

遗传算法是随机优化算法,从一个种群随机开始搜索。该算法模仿了生物进化论过程当中基因(染色体)的生存过程,此过程中的染色体充当了种群当中的个体,因此每个个体都可以作为是问题的一个解。个体在衍生的过程中不断的复制、交叉和变异,产生新的个体。通过设定的“适应值"来衡量个体,并通过“适应值”对新产生的个体进行筛选,在保持种群数量恒定的同时,选出最好的个体,得出问题的最优解。

3.1算法步骤

遗传算法的流程图如图1所示。

3.2带有时间窗的外卖车辆调度问题的遗传算法的设计

3.2.1初始种群的建立

本问题主要为VRPTW问题,采用自然数进行编码。用0表示餐馆,用1、2、…N表示待服务的人员位置。假设餐馆有C台车,则在配送过程中最多有C条服务路径,每一台车都始发于餐馆,最后也终于餐馆。为了能够使染色体中的每一个位置都可以表达一条路径,因此增加虚拟餐馆数量,增加个数为C-1个,虚拟餐馆就可以用N+1、N+2、…、N+C-1表示。则从1、2、C+N-1互不重复的自然数的排列就可以构成一个染色体,并且对应了一种配送方案。

假设,现在有12位顾客需要外卖配送,则染色体就可以表示成X={0,1,3,2,5,13,4,6,8,7,14,9,11,10,12,15}中,13,14,15为虚拟餐馆,配送的车辆为3,配送路径有三条:0-1-3-2-5-0;0-4-6-8-7-0;0-9-11-10-12-0。

3.2.2适应值筛选

为达到染色体进化过程中染色体的更新换代,必须对每个染色体进行评价。对此次配送服务主要有两个约束:

(1)时间窗约束;

(2)车辆行驶路程能力。

构建出评价函数如下:

3.2.3交叉、变异操作

基于每次的配送过程中配送任务和虚拟餐馆共同排列进行编码,所形成的染色体中的相邻元素间都是互不相同的自然数。在遗传算法中的单点和多点交叉,会造成相关配送任务的遗漏。因此选择部分映射交叉的方法。随机定义两个交叉点,交换个体交叉点之间的片段。

例如,對父代染色体A={0,1,3,2,5,13,4,6,8,7,14,9,11,10,12,15}和染色体B={0,2,1,5,7,13,4,9,3,6,14,8,12,11,10,15}进行交叉操作。

(1)随机选取交叉点3,7

A=0132513468714911101215

B=0215713943614812111015

(2)进行交叉

A=0135713968714911101215

B=0212513443614812111015

(3)对染色体A、B去重复操作

A=0135713968214411101215

B=0712513493614812111015

3.2.4变异操作

遗传算法利用变异操作产生新的个体,并且能够减弱交叉操作产生的后代适配值不在进化,并且达不到最优解时的影响。

例如,对染色体A={0,1,3,2,5,13,4,6,8,7,14,9,11,10,12,15}进行变异操作。

(1)随机选取交叉位置点3,7(对应值为2和6)

A=0132513468714911101215

(2)交换

A=0136513428714911101215​

2 仿真代码

<span style="color:#333333"><span style="background-color:rgba(0, 0, 0, 0.03)"><code>function varargout = dsxy2figxy(varargin)</code><code><span style="color:#ca7d37">if</span> <span style="color:#ca7d37">length</span>(varargin<span style="color:#dd1144">{1}</span>) == <span style="color:#0e9ce5">1</span> && ishandle(varargin<span style="color:#dd1144">{1}</span>) ...</code><code>                            && strcmp(get(varargin<span style="color:#dd1144">{1}</span>,<span style="color:#dd1144">'type'</span>),<span style="color:#dd1144">'axes'</span>)   </code><code>    hAx = varargin<span style="color:#dd1144">{1}</span>;</code><code>    varargin = varargin(<span style="color:#0e9ce5">2</span>:end);</code><code><span style="color:#ca7d37">else</span></code><code>    hAx = gca;</code><code>end</code><code><span style="color:#ca7d37">if</span> <span style="color:#ca7d37">length</span>(varargin) == <span style="color:#0e9ce5">1</span></code><code>    <span style="color:#ca7d37">pos</span> = varargin<span style="color:#dd1144">{1}</span>;</code><code><span style="color:#ca7d37">else</span></code><code>    [<span style="color:#ca7d37">x</span>,<span style="color:#ca7d37">y</span>] = deal(varargin{:});</code><code>end</code><code>axun = get(hAx,<span style="color:#dd1144">'Units'</span>);</code><code>set(hAx,<span style="color:#dd1144">'Units'</span>,<span style="color:#dd1144">'normalized'</span>); </code><code>axpos = get(hAx,<span style="color:#dd1144">'Position'</span>);</code><code>axlim = axis(hAx);</code><code>axwidth = diff(axlim(<span style="color:#0e9ce5">1</span>:<span style="color:#0e9ce5">2</span>));</code><code>axheight = diff(axlim(<span style="color:#0e9ce5">3</span>:<span style="color:#0e9ce5">4</span>));</code><code><span style="color:#ca7d37">if</span> exist(<span style="color:#dd1144">'x'</span>,<span style="color:#dd1144">'var'</span>)</code><code>    varargout<span style="color:#dd1144">{1}</span> = (<span style="color:#ca7d37">x</span> - axlim(<span style="color:#0e9ce5">1</span>)) * axpos(<span style="color:#0e9ce5">3</span>) / axwidth + axpos(<span style="color:#0e9ce5">1</span>);</code><code>    varargout<span style="color:#dd1144">{2}</span> = (<span style="color:#ca7d37">y</span> - axlim(<span style="color:#0e9ce5">3</span>)) * axpos(<span style="color:#0e9ce5">4</span>) / axheight + axpos(<span style="color:#0e9ce5">2</span>);</code><code><span style="color:#ca7d37">else</span></code><code>    <span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">1</span>) = (<span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">1</span>) - axlim(<span style="color:#0e9ce5">1</span>)) / axwidth * axpos(<span style="color:#0e9ce5">3</span>) + axpos(<span style="color:#0e9ce5">1</span>);</code><code>    <span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">2</span>) = (<span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">2</span>) - axlim(<span style="color:#0e9ce5">3</span>)) / axheight * axpos(<span style="color:#0e9ce5">4</span>) + axpos(<span style="color:#0e9ce5">2</span>);</code><code>    <span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">3</span>) = <span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">3</span>) * axpos(<span style="color:#0e9ce5">3</span>) / axwidth;</code><code>    <span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">4</span>) = <span style="color:#ca7d37">pos</span>(<span style="color:#0e9ce5">4</span>) * axpos(<span style="color:#0e9ce5">4</span> )/ axheight;</code><code>    varargout<span style="color:#dd1144">{1}</span> = <span style="color:#ca7d37">pos</span>;</code><code>end</code><code>set(hAx,<span style="color:#dd1144">'Units'</span>,axun)</code><code>​</code></span></span>

3 运行结果

4 参考文献

[1]龚艺, 冉金超, 侯明明. 基于遗传算法的多目标外卖路径规划[J]. 电子技术与软件工程, 2019(10):3.

[2]范立南, 吕鹏. 基于改进遗传算法的校园外卖配送路径规划[J]. 物流科技, 2021, 44(1):6.

博主简介:擅长智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,相关matlab代码问题可私信交流。

【路径规划】基于遗传算法实现外卖订单动态变换模型求解附matlab代码相关推荐

  1. 【优化求解】基于遗传算法优化PARSEC 方法的翼型形状附matlab代码

    1 内容介绍 航天航空技术的快速发展和市场竞争的日益激烈,导致人们对飞行器的运输效率.飞行品质和气动性能等方面的要求越来越高,使得飞行器的设计过程面临着更大的挑战.因此,对飞行器气动外形的优化设计方法 ...

  2. 【lssvm回归预测】基于遗传算法优化最小二乘支持向量机GA-lssvm实现数据回归预测附matlab代码

    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信.

  3. 【图像分割】基于计算机视觉实现视网膜图像中的血管分割附matlab代码

    1 简介 视网膜图像里的血管是可以被观察到的一类微血管,并且它是无创伤的,而其分布位置也属于深度部位[5].其分布.结构和形态特征的变化能在一定程度上反映病变的程度.而白血病.糖尿病以及高血压等疾病都 ...

  4. 基于混合整数二阶锥(MISOCP)的配电网重构(附matlab代码)

    参考资料:主动配电网网络分析与运行调控 (sciencereading.cn) 配电网重构是指在满足配电网运行基本约束的前提下,通过改变配电网中一个或多个开关的状态对配电网中一个或多个指标进行优化.通 ...

  5. 扩展卡尔曼滤波(EKF)估计SOC代码2详解,基于二阶RC模型(附MATLAB代码)

    上次分享了一个扩展卡尔曼滤波估计SOC的代码,得到了很多小伙伴的支持,今天再分享一个很好用的扩展卡尔曼滤波估计SOC的程序.使用MATLAB语言完成程序的编写. 有关EKF的推导及原理请看我写的另一个 ...

  6. 【数学建模】MATLAB应用实战系列(110)-机器人路径规划——快速扩展随机树(Rapidly-exploring Random Trees)(附Python代码)

    概率路线图(PRM)方法 原理 机器人运动规划的基本任务可以描述为:从开始位置到目标位置的运动.这一任务通常涉及到两项基本问题: 如何躲避构型空间中出现的障碍物(几何路径规划) 如何满足机器人本身在机 ...

  7. 机器人路径规划之分段三次Hermite插值(PCHIP) [包括Python和Matlab代码实现]

    前言 在机器人的路径规划中针对离散采样点做插值计算生成平滑的曲线轨迹也是挺重要的一部分,本文主要介绍一下目前使用较多也是个人觉得挺好用的一个插值方法--分段三次 Hermite 插值(PCHIP),并 ...

  8. 【回归预测-ELM预测】基于粒子群算法PSO优化极限学习机预测附matlab代码

    1 内容介绍 风电功率预测为电网规划提供重要的依据,研究风电功率预测方法对确保电网在安全稳定运行下接纳更多的风电具有重要的意义.针对极限学习机(ELM)回归模型预测结果受输入参数影响的问题,现将粒子群 ...

  9. 【回归预测-BP预测】基于灰狼算法优化BP神经网络实现数据回归预测附matlab代码

    1 内容介绍 Mirjalili 等在 2014 年 提 出 了 灰 狼 优 化 ( Grey Wolf Optimizer,GWO) 算法,是一种新型群智能优化算法,通过模拟自然界中灰狼寻找.包围和 ...

最新文章

  1. num2cell用法
  2. Outlook数据提取工具readpst
  3. db2和mysql性能_关于DB2数据库的性能分析记录
  4. 前端javascript实现二进制读写操作
  5. 这么全的数组去重,你怕不怕?
  6. C语言分区排序partition sort 算法(附完整源码)
  7. WPF企业内训全程实录(下)
  8. AtCoder Regular Contest 060
  9. C#LeetCode刷题之#643-子数组最大平均数 I( Maximum Average Subarray I)
  10. 学习Linux tar 命令:最简单也最困难
  11. 天梯—判断素数(C语言)
  12. IDEA 修改 jdk 版本
  13. android自定义软键盘
  14. 【HDU1665】That Nice Euler Circuit(欧拉公式+点在线段上判断(不在端点)+线段规范相交)
  15. xcode打包ipa配置手动配置证书
  16. 毕业论文页眉(文字)页脚(页码)插入方法
  17. 含论文基于JAVA户籍信息管理系统【数据库设计、论文、源码、开题报告】
  18. 终端操作GitHub代码以及代码的版本控制(develop/master)多图
  19. fileupload.class.php,PHP 文件上传类 FileUpload 高洛峰老师 细说PHP
  20. item_get - 根据ID获取拼多多商品详情

热门文章

  1. 5W1H聊开源之Who和How——谁、如何参与开源?
  2. Centos 7.6 Install bitnami_Redmine+agile 4.0.1
  3. 2023年中国数字孪生城市行业研究报告
  4. mybatis 项目启动时报“Result Maps collection already contains value forxxx”错误
  5. 信赖域(Trust Region)
  6. Python集合关系解读:Python语言中都有哪些集合关系?
  7. 4g网络设置dns地址_大型网络监控如何设置ip地址?如何选择交换机?
  8. js基础1 输入输出方式 数据类型
  9. “家贼”倒卖“征途”源代码 13万元卖给识货人
  10. Android Studio 3.0后,找不到Launch Standalone SDK Manager