matlab遗传算法求解带有时间窗、车载容量限制、多车辆、单配送中心路径优化VRPTW(多约束)

建立数学模型

(1)有关模型的说明和假设
1)模型中的已知量有:各需求点的位置坐标、各需求点的物料需求数量,各需求点的物料的到达时间要求,配送中心到各需求点的最短行驶距离,各需求点互相之间的最短运输距离。
2)现场调查发现,需要配送的物料是可以混装在同一物料架上的,且各需求点需要的物料数量小于物料仓库的库存量。
3)忽略在配送过程中车辆遇到的拥挤排队等不利于生产进行的外界因素,也就是说整个装配车间正常运行。同时,在配送过程中所使用的车辆的类型,速度和负载容量都是相同的,且配送车辆在车间内匀速行驶。
4)由于各生产工位对物料的消耗速度存在差异,为了更好地进行研究,将各需求点物料消耗的速度与相应的计划生产节拍保持一致,并忽略不合格产品的再生产状况。
(2)有关模型的几个约束条件
在模型建立过程中,应考虑到以下几方面约束。
1)每条配送路径上,所有需求点的物料需求量之和不超过单位配送车辆的最大装载量
2)每条配送路径上都只有一辆车进行物料配送,不能使用其他车辆进行配送,且每条路径上的每个需求点配送车辆只到达一次。
3)所有配送车辆均由同一个配送中心出阿发进行物料配送活动,配送活动结束后车辆必须返回到原配送中心,且车辆在配送过程中不存在装货的情况。
4)对同一配送路径上两个相邻的需求点来说,车辆到达前一需求点的时刻不超过到达后一需求点的时刻。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

遗传算法的主要步骤

第一步:相关参数的设定,一般主要包含编码长度L,种群大小M,迭代次数G,交叉率Pc,变异率Pm等。
第二步:算法中不能直接采用数学模型中的解进行运算,需要对解进行处理,去构造适应函数的染色体。
第三步:随机产生M个个体组成初始种群Po,并且让个体有序的分布在解空间中,每个个体为问题对应的一个解。
第四步:计算出每个个体的适应度,根据适应度进行种群中的选择和其他操作。
第五步:根据每个个体适应度的大小,选择适应度高的个体进行个体的选择等操作,通常采用的方法有轮盘赌等。
第六步:设置交叉率Pc控制父代染色体的交叉操作,被交叉的个体将代替父代进入新种群。
第七步:设置突变率Pm,控制父代染色体的突变操作。突变可导致群体中未出现或在选择过程中被淘汰的基因重新出现,突变个体取代父代进入新种群。
第八步:判断下一次迭代的选择、交叉、变异操作后的更新种群是否满足终止条件,如果不满足,则重新进入第四步进行循环迭代过程;如果满足,则停止算法运行,通常采用最大迭代次数作为终止准则。
第九步:对符合终止条件的染色体进行解码,得到问题的最优解。根据以上步骤,可知遗传算法的基本过程
在这里插入图片描述

遗传操作

1)选择操作
采用轮盘赌的方式对被选择的个体进行操作。
2)交叉操作
对选择的两个父代染色体交换其中的部分染色体去构成新的个体。本文中的交叉操作方法是部分匹配的交叉方法。首先,随机产生交叉点进行变换,之后消除重复的基因片段,交叉的具体操作如下:
亲本1:a e c /h d f g /i b
亲本2:c f a /b g h e /i d
在亲本1和2中随机生成的两个交点处于斜线位置,然后交换亲本1和亲本2斜线位置中间的基因片段,并将其放置在各个染色体头的位置以获得亲本1和亲本2,如下:
亲本1*: b g h e /a e c h d f g i b
亲本2*: h d f g /c f a b g h e i d
删除亲本1和亲本2后部与首部的重复基因得到子代1和子代2:
子代1: b g h e a c d f i
子代2: h d f g c a b e i
3)变异操作
变异是在染色体中随机位置的值进行变换,他是一种可以产生除交叉外产生新个体的方法,通过设置突变概率去随机选择单一染色体去进行操作,其中突变的方式包含了随机选择翻转,插入和交换三种突变方法。
以个染色体r=(g,a,f,h,c,b,i,d,e)为例,翻转操作为在染色体上随机产生两个割点,将割点中间部分进行翻转,假设割点为a-f和i-d之间,得到的新的染色体为rm=(g,a,i,b,c,h,f,d,e);插入操作为随机产生一个a-n中的某一个数作为变异点,假设选取的基因为i且切点位于e-g之间,将选取的基因放置于插入点,得到变异染色体rm=(g,a,f,i,h,c,b,d,e);交换操作为随机产生两个点作为被选取的两个基因,之后被选取的两个基因点进行位置互换,随机选取的基因为h和d,得到变异染色体rm= (7,a,f,d,c,b,i,h,e),详细过程如下所示。
对完成变异的新个体进行适应度的计算,把变异产生的好的结果保留,坏的剔除,这样不仅使种群的多样性得到了很好的保留,更使算法朝着更好的方向去发展。
初始染色体r:g a f h c b i d e
翻转:g a f / h c b i / d e g a i b c h f d e
插入:g a f / h c b i d e g a f i h c b d e
交换:g a f h c b i d e g a f d c b i h e

仿真实例

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

优化后数据

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

matlab代码展示

clear
clc
close all
tic
%% 用importdata这个函数来读取文件
% shuju=importdata('cc101.txt');
load('cc101');
shuju=c101;
% bl=importdata('103.txt');
bl=0;
cap=800;                                                        %车辆最大装载量
%% 提取数据信息

E=shuju(1,5);                                                    %配送中心时间窗开始时间
L=shuju(1,6);                                                    %配送中心时间窗结束时间
zuobiao=shuju(:,2:3);                                       %所有点的坐标x和y
% vertexs= vertexs./1000;
customer=zuobiao(2:end,:);                                       %顾客坐标
cusnum=size(customer,1);                                         %顾客数
v_num=6;                                                        %车辆最多使用数目
demands=shuju(2:end,4);                                          %需求量
a=shuju(2:end,5);                                                %顾客时间窗开始时间[a[i],b[i]]
b=shuju(2:end,6);                                                %顾客时间窗结束时间[a[i],b[i]]
s=shuju(2:end,7);                                                %客户点的服务时间
h=pdist(zuobiao);
% dist=load('dist1.mat');
% dist=struct2cell(dist);
% dist=cell2mat(dist);
% dist=dist./1000;                                               %实际城市间的距离
dist=squareform(h);                                             %距离矩阵,满足三角关系,暂用距离表示花费c[i][j]=dist[i][j]
%% 遗传算法参数设置
alpha=100000;                                                       %违反的容量约束的惩罚函数系数
belta=900;%违反时间窗约束的惩罚函数系数
belta2=60;
chesu=0.667;

NIND=100;                                                       %种群大小
MAXGEN=50;                                                     %迭代次数
Pc=0.9;                                                         %交叉概率
Pm=0.05;                                                        %变异概率
GGAP=0.9;                                                       %代沟(Generation gap)
N=cusnum+v_num-1;                                %染色体长度=顾客数目+车辆最多使用数目-1
% N=cusnum;
%% 初始化种群
init_vc=init(cusnum,a,demands,cap);                             %构造初始解
Chrom=InitPopCW(NIND,N,cusnum,init_vc);
%% 输出随机解的路线和总距离
disp('初始种群中的一个随机值:')

[VC,NV,TD,violate_num,violate_cus]=decode(Chrom(1,:),cusnum,cap,demands,a,b,L,s,dist,chesu,bl);
% disp(['总距离:',num2str(TD)]);
disp(['车辆使用数目:',num2str(NV),',车辆行驶总距离:',num2str(TD),',违反约束路径数目:',num2str(violate_num),',违反约束顾客数目:',num2str(violate_cus)]);
disp('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
%% 优化
gen=1;
figure;
hold on;box on
xlim([0,MAXGEN])
title('优化过程')
xlabel('代数')
ylabel('最优值')
ObjV=calObj(Chrom,cusnum,cap,demands,a,b,L,s,dist,alpha,belta,belta2,chesu,bl);             %计算种群目标函数值
preObjV=min(ObjV);
while gen<=MAXGEN
    %% 计算适应度
    ObjV=calObj(Chrom,cusnum,cap,demands,a,b,L,s,dist,alpha,belta,belta2,chesu,bl);             %计算种群目标函数值
    line([gen-1,gen],[preObjV,min(ObjV)]);pause(0.0001)%画图 最优函数
    preObjV=min(ObjV);
    FitnV=Fitness(ObjV);
    %% 选择
    SelCh=Select(Chrom,FitnV,GGAP);
    %% OX交叉操作
    SelCh=Recombin(SelCh,Pc);
    %% 变异
    SelCh=Mutate(SelCh,Pm);
    %% 局部搜索操作
    SelCh=LocalSearch(SelCh,cusnum,cap,demands,a,b,L,s,dist,alpha,belta,belta2,chesu,bl);
    %% 重插入子代的新种群
    Chrom=Reins(Chrom,SelCh,ObjV);
    %% 删除种群中重复个体,并补齐删除的个体
    Chrom=deal_Repeat(Chrom);
    %% 打印当前最优解
    ObjV=calObj(Chrom,cusnum,cap,demands,a,b,L,s,dist,alpha,belta,belta2,chesu,bl);             %计算种群目标函数值
    [minObjV,minInd]=min(ObjV);
    disp(['第',num2str(gen),'代最优解:'])
    [bestVC,bestNV,bestTD,best_vionum,best_viocus]=decode(Chrom(minInd(1),:),cusnum,cap,demands,a,b,L,s,dist,chesu,bl);
    disp(['车辆使用数目:',num2str(bestNV),',车辆行驶总距离:',num2str(bestTD),',违反约束路径数目:',num2str(best_vionum),',违反约束顾客数目:',num2str(best_viocus)]);
    fprintf('\n')
    %% 更新迭代次数
    gen=gen+1 ;
end
%% 画出最优解的路线图
ObjV=calObj(Chrom,cusnum,cap,demands,a,b,L,s,dist,alpha,belta,belta2,chesu,bl);             %计算种群目标函数值
[minObjV,minInd]=min(ObjV);
%% 输出最优解的路线和总距离
disp('最优解:')
bestChrom=Chrom(minInd(1),:);
[bestVC,bestNV,bestTD,best_vionum,best_viocus]=decode(bestChrom,cusnum,cap,demands,a,b,L,s,dist,chesu,bl);
disp(['车辆使用数目:',num2str(bestNV),',车辆行驶总距离:',num2str(bestTD),',违反约束路径数目:',num2str(best_vionum),',违反约束顾客数目:',num2str(best_viocus)]);
disp('-------------------------------------------------------------')
%% 判断最优解是否满足时间窗约束和载重量约束,0表示违反约束,1表示满足全部约束
flag=Judge(bestVC,cap,demands,a,b,L,s,dist,chesu,bl);
%% 检查最优解中是否存在元素丢失的情况,丢失元素,如果没有则为空
DEL=Judge_Del(bestVC,cusnum);
init_v=vehicle_load(bestVC,demands);
%% 画出最终路线图
draw_Best(bestVC,zuobiao);

如需帮助请联系我(代码或代写)
在这里插入图片描述

相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页