一、简介
1 背景
仓库布局为flying-V型宽道模式,即不考虑拣货小车本身大小,多辆小车可同时在路径上行走。如下图:(约束条件为载重时间窗等,目标为最低成本)
两条主干道,4个区。零部件货物坐标表示为[A,x,y],例如[2,3,5]表示该零部件位于第二区第三排的第五列,存取点坐标例外为[0,0,0]。这样设货架长度为L,可计算出两个货物之间的距离。本文是基于Flying-V型仓库探讨拣货小车路径问题,对于多个分散在不同区域的零部件,调用一定数量的车辆,满足一定的约束条件达到路径较短,总成本最低等综合目标,属于经典车辆路径问题(VRP)。本次设计主要讨论在软时间窗条件(允许超出货物被拣规定的时间,根据超出的时间进行惩罚附加额外的成本,硬时间窗则不允许超出时间,需要重新规划路线),车辆数量,车辆装载率以及路线成本下设计各自的成本权重,得出总成本的单目标函数。因此总成本包括车辆的基本费用、路程油耗、时间惩罚成本和车辆载重附加油耗。K辆载重为W的同类型拣货小车,从一个存取点出发负责对N个零部件进行拣货工作,记为节点(i=0,1,2,…,n),每个零部件有各自对应的重量wi,有各自的被拣时间范围[ai,bi],在一定的假设条件下安排车辆数量和每辆车的行驶路线使总成本达到最小。
根据以上条件可列出各个货物的距离矩阵。此时若有一定的小车车队及对应路线则可以根据设定的单位成本计算出总成本。
有了总成本的计算方法那么如何得出小车路线是关键的,遗传算法则是根据已设定好的初始种群路线计算对应的成本适应度函数进行选择交叉变异等操作不断进化达到多约束条件下的最优解,即最优路线。
假设有9个零部件货物,举例如下:1 5 6 9 2 8 3 5 7 4 零部件1-9对应的重量分别为 1 3 5 8 2 2 11 4 9,小车的载重为13,由于w1+w5+w6=5,w1+w5+w6+w9=14>13,故派出第一辆小车负责零部件1 5 6的运送。同理第二辆车负责零部件9 2的运送,第三辆车负责8 3 5的运送,第四辆车只运送零部件7,第五辆车只负责零部件4,因此一共需要5辆小车。根据得到的车辆数目和每辆小车各自负责运送的零部件货物顺序进行下一步的操作。
每个货物有对应的重量和被拣的时间范围,小车为同种小车有载重重量,小车有行驶速度,本文是设定35个货物零部件,能派出的小车数量不限,初始种群大小为100,每个个体对应一段路线,为自然数编码即根据货物的编号来确定路线。根据载重条件后可得出小车数量和每辆小车各自对应的路线。
在每一代的更新后与上一代各个个体进行比较进行模拟退火的优化,以便得出最优解。
产生新的种群后将新种群的适应度与原种群作比较,加入Metropolis接受准则,即以一定概率接受新种群中的较差解,完全接受新种群的更优解。这样便大大的增加了跳出局部最优解的概率。如图当算法陷入局部最优解A时,加入该接受准则可有利于该算法跳出局部最优解,当得到下一个高峰点时,由于附近的解都劣于该解,故大大的增加了得到最优解C的概率。
二、源代码
clear all;
clc;
tic
%%
load D;%数据,包括L长度,最大行数,最大列数,一个小车最大载重量
load time;%加载各个货物的时间范围
load GoodPosition;
load weight;%各个货物的重量;
Good_N = size(Good_P,1); %货物坐标矩阵一维得出货物数量
for i=1:Good_N
if(mod(Good_P(i,2),2)==0)
if(Good_P(i,3)>(Good_P(i,2)/2-1)*3+1)
if(Good_P(i,1)==1)
Good_P(i,1)=4;
else Good_P(i,1)=3;
end
end
else
if(Good_P(i,3)>(Good_P(i,2)-1)/2*3)
if(Good_P(i,1)==1)
Good_P(i,1)=4;
else Good_P(i,1)=3;
end
end
end
end
%% 遗传参数
POP = 100; %种群大小
MAXGEN = 250;%迭代次数
GAP = 0.9;
PC = 0.6;%交叉概率
%PM = 0.9;%变异概率
PM = 0.05;%变异概率
PM_dec = PM/MAXGEN;%变异概率逐渐减小,保证算法收敛
temper = 90;%模拟退火温度
temper_dec =0.99;%温度下降比例
record_length = zeros(MAXGEN,1);
%约束条件及其费用
t = 1.5; %行驶单位距离所用时间s
Cr = 500; %单位小车基本费用角
Cd =0.04; %单位路程油耗角
Cw = 0.02;%单位载重附加油耗角
Ct = 0.1;%时间惩罚单位成本角
C=[Cr,Cd,Cw,Ct];
%%初始化种群
gen =1;
chrom = Init_Pop(POP,Good_N);
temp = zeros(POP,1);
chrom = [temp,chrom];%路径加入起点0
weight_chrom=cell(size(chrom,1),1);
weight_chrom = Distribute(chrom,D,weight);
weight_chrom_old = weight_chrom;%模拟退火记录原种群
Length = Distance(weight_chrom,Good_P,D); %计算种群个体所对应的路径距离
money = Money(Length,weight_chrom,t,C,weight,time,Good_P,D);%计算种群各个个体的路径总成本;
[min_length,min_index_length] = min(Length);
record_length(gen,:) = Length(min_index_length,:);%记录迭代中最优个体
record_mean_length(gen,:) = mean(Length);%记录迭代中个体平均值
record_money(gen,:) = money(min_index_money);
record_mean_money(gen,:)=mean(money);
money_route_length(gen,:) = Length(min_index_money);
best_route = weight_chrom{min_index_money,1};
best_length = min_length;
best_money = min_money;
%% 种群更新优化
while(gen<=MAXGEN)
Length = Distance(weight_chrom,Good_P,D);
money = Money(Length,weight_chrom,t,C,weight,time,Good_P,D);
[min_length,min_index_length] = min(Length);
record_length(gen,:) = Length(min_index_length,:);
record_mean_length(gen,:) = mean(Length);
[min_money,min_index_money]=min(money);
record_money(gen,:) = money(min_index_money);
record_mean_money(gen,:)=mean(money);
money_route_length(gen,:) = Length(min_index_money);
if min_money<best_money;
best_money = min_money;
best_route = weight_chrom{min_index_money,1};
end
if min_length <best_length
best_length = min_length;
end
function Length = Distance(weight_chrom,Good_P,D)
POP = size(weight_chrom,1);
Length = zeros(POP,1);
% for i =1:POP
% for j = 1:(size(chrom,2)-1)%每个个体两点之间,把Good_P
% Length(i,:) = Length(i,:)+Two_D ( Good_P,chrom(i,j),chrom(i,j+1),D);
% end
% Length(i,:) = Length(i,:) + Two_D(Good_P,chrom(i,end),chrom(i,1),D);
% end
function length = Two_D(Good_P,N1,N2,D)
%%
l = D(1);
if(N1==0 ||N2==0)
if(N1==0 )
A1=0;x1=0;y1=0;
A2= Good_P(N2,1);
x2 = Good_P(N2,2);
y2 = Good_P(N2,3);
end
if(N2==0)
A2=0;x2=0;y2=0;
A1 = Good_P(N1,1);
x1 = Good_P(N1,2);
y1 = Good_P(N1,3);
end
else
A1 = Good_P(N1,1);
x1 = Good_P(N1,2);
y1 = Good_P(N1,3);
A2 = Good_P(N2,1);
x2 = Good_P(N2,2);
y2 = Good_P(N2,3);
end
if(mod(x1,2)==1) x1=x1-1;end
if(mod(x2,2)==1) x2=x2-1;end
length_mid1=abs(x1/2+x1+1-y1)*l;
length_mid2=abs(x2/2+x2+1-y2)*l;
length_midcol = abs(x1-x2)/2*3*sqrt(2)*l;
if(A1==0) L1=0; end;
if(A2==0) L2=0; end;
if(A1==1||A1==2)
L1=(x1/2+x1)*sqrt(2)*l+(x1/2+x1+1-y1)*l;%货物到存取点距离
else
L1=(y1-1-(x1/2-1)*3)*l+(x1/2+x1)*sqrt(2)*l;
end
if(A2==1||A2==2)
L2=(x2/2+x2)*sqrt(2)*l+(x2/2+x2+1-y2)*l;
else
L2=(y2-1-(x2/2-1)*3)*l+(x2/2+x2)*sqrt(2)*l;
end%点1和点2到存取点的距离
if((A1==A2&A1==1)||(A1==A2&&A1==2))%1区到1区 2区到2区
if(x1==x2)
length = abs(y1-y2)*l;
else
length = length_mid1+length_midcol+length_mid2;
end
else if((A1==A2&A1==4)||(A1==A2&&A1==3))%4区到4区 3区到3区
if(x1==x2)
length = abs(y1-y2)*l;
else
else length = L1+L2;
end
end
三、运行结果
四、备注