在之前最后一公里极速配送(三)中提到的上传代码少了一个文件,下面将DataProcess.m代码公布如下,注意程序的运行方式:首先运行DataProcess.m,其次运行VPRPSO.m文件(这里可能需要等待5个多小时,与处理器速度有关),这个程序运行完了,下面再运行result程序,最后再运行Arrange程序,输出的表格即为EC订单的处理结果。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%一 读取原始数据
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%1 网点经纬度
% function DataProcess
clear;clc
fid = fopen('1.csv');
Site = textscan(fid, '%s %f %f ', 'delimiter', ',');
fclose(fid);
Site_id1=Site{1};Lng1=Site{2};Lat1=Site{3};
%2 配送点经纬度
fid = fopen('2.csv');
Spot= textscan(fid, '%s %f %f ', 'delimiter', ',');
fclose(fid);
Spot_id2=Spot{1};Lng2=Spot{2};Lat2=Spot{3};
%3 商户经纬度
fid = fopen('3.csv');
Shop = textscan(fid, '%s %f %f ', 'delimiter', ',');
fclose(fid);
Shop_id3=Shop{1};Lng3=Shop{2};Lat3=Shop{3};
%4 电商订单
fid = fopen('4.csv');
Online_retailer = textscan(fid, '%s %s %s %d ', 'delimiter', ',');
fclose(fid);
Order_id4=Online_retailer{1};Spot_id4=Online_retailer{2};
Site_id4=Online_retailer{3};Num4=Online_retailer{4};
%5 同城O2O订单
fid = fopen('5.csv');%Site_id=Site{1};Lng1=Site{2};Lat1=Site{3};
O2O = textscan(fid, '%s %s %s %s %s %d ', 'delimiter', ',');
fclose(fid);
Order_id5=O2O{1};Spot_id5=O2O{2};
Site_id5=O2O{3};Pickup_time=O2O{4};
Delivery_time=O2O{5};Num5=O2O{6};
%6 快递员列表
fid = fopen('6.csv');
Courier_id = textscan(fid, '%s ', 'delimiter', ',','HeaderLines',1);
fclose(fid);
clear fid ans Site Spot Shop Online_retailer O2O
% 二 聚类
%1 O2O商户对应最近的配送点
% for i=1:length(Lng3)
% for j=1:length(Lng2)
% S(i,j)=Distance(Lat3(i),Lng3(i),Lat2(j),Lng2(j));
% end
% [result1(i),class1(i)]=min(S(i,:));%result1(i),class1(i)分别存放每个商户距离最近配送点值和配送点标号
% end
%2 每个配送点对应的最近网站聚类
% tic
% for i=1:length(Lng2)
% for j=1:length(Lng1)
% S(i,j)=Distance(Lat2(i),Lng2(i),Lat1(j),Lng1(j));
% end
% [result2(i),class2(i)]=min(S(i,:));%result1(i),class1(i)分别存放每个配送点距离最近网点值和网点标号
% end
% toc
% for i=1:124
% [a1{i},a2{i}]=find(class2==i);%a2{i}存放第个网点对应的配送点编号
% end
%%先配送完电商的货物
%采用Floyd 算法求解124个网点中的配送点和网点两两之间的距离
for i=1:length(Site_id1)
%Spot中存放的是第i个网点对应配送点的标号
Index4{i}=(strmatch(Site_id1{i} , Site_id4));%第i个网点对应配送点在电商订单中所对应的ID号
Demand{i}=Num4((strmatch(Site_id1{i} , Site_id4)));%第i个网点对应配送点在的需求量
[Spa{i},Spb{i}]=ismember(Spot_id4(strmatch(Site_id1{i} , Site_id4)),Spot_id2);
%Spb{i}表示第i个网点对应配送点在自己Map图中编号
% coordinations{i}(:,1)=Lat2((strmatch(Site_id{i} , Site_id4)));
% coordinations{i}(:,2)=Lng2((strmatch(Site_id{i} , Site_id4)));
%%下面originData是很重要的一个输出数据矩阵
originData{i}=zeros(length((strmatch(Site_id1{i} , Site_id4)))+1,1);%初始化originData
originData{i}(1,1)=i;
originData{i}(1,2)=Lat1(i);%第二列存放Lat
originData{i}(1,3)=Lng1(i);%第三列存放Lng
originData{i}(1,4)=0;%第四列存放需求量
originData{i}(1,5)=0;%第5列存放pickup_time
originData{i}(1,6)=720;%第6列存放deliver_time
originData{i}(1,7)=0;%第7列存放服务时间
%originData{i}(1,8)=0;
originData{i}(2:end,1)=Index4{i};%第一列存放电商订单编号
originData{i}(2:end,2)=Lat2(Spb{i});%第二列存放Lat
originData{i}(2:end,3)=Lng2(Spb{i});%第三列存放Lng
originData{i}(2:end,4)=Demand{i};%第四列存放需求量
%时间窗口
originData{i}(2:end,5)=0;%第5列存放pickup_time
originData{i}(2:end,6)=0;%第6列存放deliver_time
originData{i}(2:end,7)=3*sqrt(double(Demand{i}))+5;%第7列存放服务时间t=3*sqrt(demand)+5
%originData{i}(2:end,8)=Order_id4{Index4{i}};%第2列对应的是编号Index4所对应的快递order_Id
%A{i}=Order_id4{Index4{i}};
%IDData{1,i}(1,1)=Site_id{i}(:);
%IDData{i,2}=0;
% IDData{i}(2:end,8)=Spot_id4{Index4{i}};%第1列位快递所对应的配送点Id和相应的网点Id
% IDData{i}(2:end,9)=Order_id4{Index4{i}};%第2列对应的是编号Index4所对应的快递order_Id
end
%Matlab中的细胞数组字节对其与C语言不一样
% for i=1:length(Site_id)
% for j=1:length(Spb{i})
% Spb{i}(length(Spb{i})+1)=0;
% Spb{i}(length(Spb{i})-j+2)=Spb{i}(length(Spb{i})-j+1);
% %Spb{i}(1)=i;
% end
% end
%对于每个网点的配送点和网点求两两之间的距离
tic
S(1,1)=eps;
for k=1:length(Site_id1)
for i=1:length(Spb{k})
S(i+1,1)=Distance(Lat2(Spb{k}(i)),Lng2(Spb{k}(i)),Lat1(k),Lng1(k));%第一列表示网点与配送点之间距离
S(i,i)=eps;
for j=1:length(Spb{k})
S(1,j+1)=Distance(Lat1(k),Lng1(k),Lat2(Spb{k}(j)),Lng2(Spb{k}(j)));%第一行表示网点与配送点之间距离
S(i+1,j+1)=Distance(Lat2(Spb{k}(i)),Lng2(Spb{k}(i)),Lat2(Spb{k}(j)),Lng2(Spb{k}(j)));
end
end
D{k}=S;%D中存放的是124个网点对应的配送点两两之间的距离
clear S;
end
%第一个点是124个网点中的一个
toc
%将时间窗口点转化为分钟(标准)
for i=1:length(Delivery_time)
Pickup_time5(i,1)=(str2num(Pickup_time{i}(1:2))-8)*60+str2num(Pickup_time{i}(4:5));
Delivery_time5(i,1)=(str2num(Delivery_time{i}(1:2))-8)*60+str2num(Delivery_time{i}(4:5));
end
save D
save originData
save Courier_id
save Order_id4
save Spot_id4
save Site_id1
至于O2O的配送应该每个人的做法都不一样,比赛结束后会公布我的设计算法!