【路径规划】基于遗传算法求解静态外卖骑手路径规划附matlab代码

 1 简介

​据中国互联网络信息中心发布的第 44 次《中国互联网络发展状况统计报告》指出,截至 2019 年 6 月,我国网民规模达到 8.54 亿,较 2018 年底增长 2598 万,互联网普及率达 61.2%,其中手机网民占比高达 99.1%。庞大的网民数量为 O2O(Online ToOffline)业态的发展壮大奠定了坚实的用户基础,移动设备以及互联网的普及使得用户的 O2O 行为(连接线上线下的行为)更加高效,加上人工智能、大数据和 5G 等互联网技术的发展应用,O2O 模式得以进入更加广阔的线下领域,逐步渗透人们的日常生活。正所谓民以食为天,餐饮行业用户基数大,消费频次高,易形成较大的市场规模,因此 O2O 业态中以餐饮外卖 O2O 产业发展最为迅猛。随着业务的下沉,越来越多三四线城市的商户入驻外卖平台,用户粘性逐渐养成,外卖生态体系布局初现。目前我国外卖用户数已达 4.21 亿,占到整体网民的 49.3%,2019 年中国外卖产业交易额已突破六千亿,而外卖交易额占全国餐饮总收入比例仍在持续增长,其中一个很重要的原因是新零售时代的到来,用户需求更为多元,从单纯的餐饮领域向非餐饮、全品类跨越,实物配送需求大幅增加。如今的外卖服务已经外溢到生鲜果蔬、生活超市、美妆、日用品、服饰鞋帽和母婴产品等更多生活场景,这使得外卖成为了全时段、跨品类的重要消费场景。

外卖行业发展至今,行业格局已发生巨变,外卖商家渗透率持续提升,外卖平台多元入口引流,C 端市场格局已经稳定,白领用户的主体地位牢不可破,餐饮场景日益丰富,非正餐外卖需求(下午茶、夜宵等)增长显著。相应的,外卖智能调度系统技术不断优化,行业配送效率整体提升,外卖配送网络的服务承载持续扩大,即时配送网络已经成为基础设施,且不仅服务于餐饮外卖领域,进而为本地生活市场服务,加速推动了各项业务的全面协同。随着外卖行业的持续发展以及门槛低、回报率高的特点,外卖骑手快速扩增,外卖骑手日活跃用户数量高达 57 万,在满足人们便利性的同时,也为民众的日常出行带来了新的挑战,目前出台的相关法律制度不能对其进行很好的约束,监管难度大,民众对于外卖小哥的认可度不高,而如今外卖渗透率仍不足 15%,未来还有持续的成长空间,提升全民认可度对外卖 O2O 产业的继续发展具有重要意义。因此,外卖 O2O 模式的线下配送服务仍是当前研究的重点,如何设计合理的配送路径方案,在满足消费者需求、实现企业获得较高盈利的基础上,缓解交通状况、提高全民的认可度成为了一个亟待解决的问题

基于大连市某外卖配送站点的运营实例,针对午餐高峰时段涌入的大量订单,对骑手的配送路径进行优化.以最大化运输效率为目标,综合考虑外卖配送的实际约束,有针对性地构建骑手配送路径优化的混合整数规划模型,利用遗传算法对实例进行求解,详细分析了算法参数对优化结果的影响机理,可为外卖配送行业提供决策支持.

2 部分代码


%% 找出Removed数组中任一个元素的cheapest insertion point
%输入rv                               Removed数组中的任一个元素
%输入rfvc                             移出removed中的顾客后的final_vehicles_customer
%输入L                                集配中心时间窗
%输入a                                顾客时间窗
%输入b                                顾客时间窗
%输入s                                服务每个顾客的时间
%输入dist                             距离矩阵
%输入demands                          需求量
%输入cap                              最大载重量
%输出civ
%将rv插入到rfvc中在满足容量和时间窗约束下的距离增量最小的那辆车
%输出cip
%将rv插入到rfvc中在满足容量和时间窗约束下的距离增量最小的那辆车中的插入点
%输出C                                将rv插入到最佳插入点后的距离增量

%思路:
%第一步:先找出满足时间窗约束和容量约束的所有插入点,再计算上述插入点的距离增量
%第二步:找出上述插入点距离增量最小的那个最佳插入点,并记录距离增量
function [civ,cip,C]= cheapestIP( rv,rfvc,L,a,b,s,dist,demands,cap,chesu,bl)
NV=size(rfvc,1);              %所用车辆数
outcome=[];                 %存储每一个合理的插入点以及对应的距离增量 [车辆序号 插入点序号 距离增量]
for i=1:NV
    route=rfvc{i};          %其中的一条路径
    len=length(route);      %该路径上所经过顾客数量
    LB= part_length(route,dist);       %插入rv之前该条路径的距离
    %先将rv插入到route中的任何空隙,共(len+1)个,
    for j=1:len+1;
        %将rv插入到集配中心后
        if j==1
            temp_r=[rv route];
            LA= part_length(temp_r,dist);       %插入rv之后该条路径的距离
            delta=LA-LB;                       %插入rv之后该条路径的距离增量
            [bs,back]= begin_s(temp_r,a,s,dist,chesu,bl );
            %因为b是100行1列,所以需要将bs转置成多行1列的矩阵
            violate_TW=(bs'<=b(temp_r));          %判断每一个顾客是否满足时间窗约束,满足为1,不满足为0
            vTW=find(violate_TW==0,1,'first');  %找出violate_TW数组中不满足时间窗约束的顾客
            Ld=leave_load( temp_r,demands);
            %如果同时满足时间窗约束和容量约束,则该插入点合理,并记录下来
            if isempty(vTW)&&(back<=L)&&(Ld<=cap)
                outcome=[outcome;i j delta];
            end
            %将rv插入到集配中心前
        elseif j==len+1
            temp_r=[route rv];
            LA= part_length(temp_r,dist);       %插入rv之后该条路径的距离
            delta=LA-LB;                       %插入rv之后该条路径的距离增量
            [bs,back]= begin_s( temp_r,a,s,dist,chesu,bl );
            %因为b是100行1列,所以需要将bs转置成多行1列的矩阵
            violate_TW=(bs'<=b(temp_r));          %判断每一个顾客是否满足时间窗约束,满足为1,不满足为0
            vTW=find(violate_TW==0,1,'first');  %找出violate_TW数组中不满足时间窗约束的顾客
            Ld=leave_load( temp_r,demands);
            %如果同时满足时间窗约束和容量约束,则该插入点合理,并记录下来
            if isempty(vTW)&&(back<=L)&&(Ld<=cap)
                outcome=[outcome;i j delta];
            end
            %将rv插入到顾客之间的任意空隙
        else
            temp_r=[route(1:j-1) rv route(j:end)];
            LA= part_length(temp_r,dist);       %插入rv之后该条路径的距离
            delta=LA-LB;                       %插入rv之后该条路径的距离增量
            [bs,back]= begin_s( temp_r,a,s,dist,chesu,bl );
            %因为b是100行1列,所以需要将bs转置成多行1列的矩阵
            violate_TW=(bs'<=b(temp_r));          %判断每一个顾客是否满足时间窗约束,满足为1,不满足为0
            vTW=find(violate_TW==0,1,'first');  %找出violate_TW数组中不满足时间窗约束的顾客
            Ld=leave_load( temp_r,demands);
            %如果同时满足时间窗约束和容量约束,则该插入点合理,并记录下来
            if isempty(vTW)&&(back<=L)&&(Ld<=cap)
                outcome=[outcome;i j delta];
            end
        end
    end
end
%% 如果存在合理的插入点,则找出最优插入点,否在新增加一辆车运输
if ~isempty(outcome)
    addC=outcome(:,3);                          %每个插入点的距离增量
    [saC,sindex]=sort(addC);                    %将距离增量从小到达排序
    temp=outcome(sindex,:);                     %将距离增量从小到达排序后的[车辆序号 插入点序号 距离增量]
    civ=temp(1,1);                              %第一行即为最佳插入点以及对应的距离增量
    cip=temp(1,2);
    C=temp(1,3);
else
    civ=NV+1;
    cip=1;
    C=part_length(rv,dist);
end

end


%% 初始化路径
%输入cusnum   顾客数量 1-100
%输入a        左时间窗 [a,b],最早允许开始服务时间
%输入demands  每个顾客的需求量
%输入cap      车辆最大载货量
%% 先选一个12345---45123   
function [init_vc] = init(cusnum,a,demands,cap)
j=ceil(rand*cusnum);                    %从所有顾客中随机选择一个顾客
k=1;                                    %使用车辆数目,初始设置为1
init_vc=cell(k,1);
% 按照如下序列,遍历每个顾客,并执行以下步骤
if j==1
    seq=1:cusnum;
elseif j==cusnum
    seq=[cusnum,1:j-1];
else
    seq1=1:j-1;
    seq2=j:cusnum;
    seq=[seq2,seq1];                      
end
%% 开始遍历
route=[];       %存储每条路径上的顾客
load=0;         %初始路径上在仓库的装载量为0
i=1;
while i<=cusnum
    %如果没有超过容量约束,则按照左时间窗大小,将顾客添加到当前路径
    %%
    if (load+demands(seq(i))<=cap)&&(size(route,1)<=20)    %%%%自己家的条件****************   
    %%  
        load=load+demands(seq(i));          %初始在仓库的装载量增加
        %如果当前路径为空,直接将顾客添加到路径中
        if isempty(route)
            route=[seq(i)];
        %如果当前路径只有一个顾客,再添加新顾客时,需要根据左时间窗大小进行添加
        elseif length(route)==1
            if a(seq(i))<=a(route(1))
                route=[seq(i),route];   
            else
                route=[route,seq(i)];
            end
        else
            lr=length(route);       %当前路径长度,则有lr-1对连续的顾客
            flag=0;                 %标记是否存在这样1对顾客,能让seq(i)插入两者之间
            %遍历这lr-1对连续的顾客的中间插入位置
            for m=1:lr-1
                if (a(seq(i))>=a(route(m)))&&(a(seq(i))<=a(route(m+1)))
                    route=[route(1:m),seq(i),route(m+1:end)];
                    flag=1;
                    break
                end
            end
            %如果不存在这样1对顾客,能让seq(i)插入两者之间,也就是flag=0,则需要将seq(i)插到route末尾
            if flag==0
                route=[route,seq(i)];
            end
        end
        %如果遍历到最后一个顾客,则更新init_vc,并跳出程序
        if i==cusnum
            init_vc{k,1}=route;
            break
        end
        i=i+1;
    else   %一旦超过车辆载货量约束,则需要增加一辆车
        %先储存上一辆车所经过的顾客
        init_vc{k,1}=route;
        %然后将route清空,load清零,k加1
        route=[];
        load=0;
        k=k+1;
    end
end
end


%% 根据vehicles_customer整理出final_vehicles_customer,将vehicles_customer中空的数组移除
%输入:vehicles_customer        每辆车所经过的顾客
%输出:final_vehicles_customer  删除空数组,整理后的vehicles_customer
function [ final_vehicles_customer,vehicles_used ] = deal_vehicles_customer( vehicles_customer )
vecnum=size(vehicles_customer,1);               %车辆数
final_vehicles_customer={};                     %整理后的vehicles_customer
count=1;                                        %计数器
for i=1:vecnum
    par_seq=vehicles_customer{i};               %每辆车所经过的顾客
    %如果该辆车所经过顾客的数量不为0,则将其所经过的顾客数组添加到final_vehicles_customer中
    if ~isempty(par_seq)                        
        final_vehicles_customer{count}=par_seq;
        count=count+1;
    end
end
%% 为了容易看,将上述生成的1行多列的final_vehicles_customer转置了,变成多行1列的了
final_vehicles_customer=final_vehicles_customer';       
vehicles_used=size(final_vehicles_customer,1);              %所使用的车辆数
end

3 仿真结果

4 参考文献

[1]靳志宏, 鞠新诚, 郭加佳,等. O2O模式下外卖骑手的配送路径优化[J]. 大连海事大学学报, 2019, 45(4):10.

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

部分理论引用网络文献,若有侵权联系博主删除。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

matlab科研助手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值