【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】

一、简介

1 前言:
灰狼优化算法(Grey Wolf Optimizer,GWO)由澳大利亚格里菲斯大学学者 Mirjalili 等人于2014年提出来的一种群智能优化算法。该算法受到了灰狼捕食猎物活动的启发而开发的一种优化搜索方法,它具有较强的收敛性能、参数少、易实现等特点。近年来受到了学者的广泛关注,它己被成功地应用到了车间调度、参数优化、图像分类等领域中。
2 算法原理:
灰狼隶属于群居生活的犬科动物,且处于食物链的顶层。灰狼严格遵守着一个社会支配等级关系。如图:
【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】
社会等级第一层:狼群中的头狼记为 \alpha,\alpha 狼主要负责对捕食、栖息、作息时间等活动作出决策。由于其它的狼需要服从\alpha 狼的命令,所以 \alpha 狼也被称为支配狼。另外, \alpha 狼不一定是狼群中最强的狼,但就管理能力方面来说, \alpha 狼一定是最好的。

社会等级第二层:\beta 狼,它服从于 \alpha 狼,并协助 \alpha 狼作出决策。在 \alpha 狼去世或衰老后,\beta 狼将成为 \alpha 狼的最候选者。虽然 \beta 狼服从 \alpha 狼,但 \beta 狼可支配其它社会层级上的狼。

社会等级第三层:\delta 狼,它服从 \alpha 、\beta 狼,同时支配剩余层级的狼。\delta 狼一般由幼狼、哨兵狼、狩猎狼、老年狼及护理狼组成。

社会等级第四层:\omega 狼,它通常需要服从其它社会层次上的狼。虽然看上去 \omega 狼在狼群中的作用不大,但是如果没有 \omega 狼的存在,狼群会出现内部问题如自相残杀。

GWO 优化过程包含了灰狼的社会等级分层、跟踪、包围和攻击猎物等步骤,其步骤具体情况如下所示。

1)社会等级分层(Social Hierarchy)当设计 GWO 时,首先需构建灰狼社会等级层次模型。计算种群每个个体的适应度,将狼群中适应度最好的三匹灰狼依次标记为 \alpha、\beta 、\delta ,而剩下的灰狼标记为 \omega。也就是说,灰狼群体中的社会等级从高往低排列依次为; \alpha、\beta 、\delta 及 \omega。GWO 的优化过程主要由每代种群中的最好三个解(即 \alpha、\beta 、\delta )来指导完成。

2)包围猎物( Encircling Prey )灰狼捜索猎物时会逐渐地接近猎物并包围它,该行为的数学模型如下:
【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】
式中:t 为当前迭代次数:。表示 hadamard 乘积操作;A 和 C 是协同系数向量;Xp 表示猎物的位置向量; X(t) 表示当前灰狼的位置向量;在整个迭代过程中 a 由2 线性降到 0; r1 和 r2 是 [0,1] 中的随机向量。

3)狩猎( Hunring)

灰狼具有识别潜在猎物(最优解)位置的能力,搜索过程主要靠 \alpha、\beta 、\delta 灰狼的指引来完成。但是很多问题的解空间特征是未知的,灰狼是无法确定猎物(最优解)的精确位置。为了模拟灰狼(候选解)的搜索行为,假设 \alpha、\beta 、\delta 具有较强识别潜在猎物位置的能力。因此,在每次迭代过程中,保留当前种群中的最好三只灰狼( \alpha、\beta 、\delta ),然后根据它们的位置信息来更新其它搜索代理(包括 \omega)的位置。该行为的数学模型可表示如下:
【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】
式中:X_{{\alpha }}、X{{\beta }}、X{{\delta }} 分别表示当前种群中 \alpha、\beta 、\delta 的位置向量;X表示灰狼的位置向量;D{{\alpha }}、D{{\beta }}、D{_{\delta }} 分别表示当前候选灰狼与最优三条狼之间的距离;当|A|>1时,灰狼之间尽量分散在各区域并搜寻猎物。当|A|<1时,灰狼将集中捜索某个或某些区域的猎物。
【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】
从图中可看出,候选解的位置最终落在被 \alpha、\beta 、\delta 定义的随机圆位置内。总的来说, \alpha、\beta 、\delta 需首先预测出猎物(潜
在最优解)的大致位置,然后其它候选狼在当前最优兰只狼的指引下在猎物附近随机地更新它们的位置。

4)攻击猎物(Attacking Prey)构建攻击猎物模型的过程中,根据2)中的公式,a值的减少会引起 A 的值也随之波动。换句话说,A 是一个在区间[-a,a](备注:原作者的第一篇论文里这里是[-2a,2a],后面论文里纠正为[-a,a])上的随机向量,其中a在迭代过程中呈线性下降。当 A 在[-1,1]区间上时,则捜索代理(Search Agent)的下一时刻位置可以在当前灰狼与猎物之间的任何位置上。

5)寻找猎物(Search for Prey)灰狼主要依赖 \alpha、\beta 、\delta 的信息来寻找猎物。它们开始分散地去搜索猎物位置信息,然后集中起来攻击猎物。对于分散模型的建立,通过|A|>1使其捜索代理远离猎物,这种搜索方式使 GWO 能进行全局搜索。GWO 算法中的另一个搜索系数是C。从2)中的公式可知,C向量是在区间范围[0,2]上的随机值构成的向量,此系数为猎物提供了随机权重,以便増加(|C|>1)或减少(|C|<1)。这有助于 GWO 在优化过程中展示出随机搜索行为,以避免算法陷入局部最优。值得注意的是,C并不是线性下降的,C在迭代过程中是随机值,该系数有利于算法跳出局部,特别是算法在迭代的后期显得尤为重要。

3 VRP问题描述:
假设在一个供求关系系统中,车辆从货源取货,配送到对应的若干配送点。车辆存在最大载货量,且配送可能有时间限制。需要合理安排取货时间,组织适当的行车路线,使用户需求得到满足,同时使某个代价函数最小,比如总工作时间最少、路径最短等。

可以看出TSP问题是VRP问题的一种简单特殊形式。因此,VRP也是一种NP hard 问题。

二、源代码

tic
clear
clc
%% 用importdata这个函数来读取文件
c101=importdata('c101.txt');
cap=200;        
%% 提取数据信息
E=c101(1,5);                                                    %配送中心时间窗开始时间
L=c101(1,6);                                                    %配送中心时间窗结束时间
vertexs=c101(:,2:3);                                            %所有点的坐标x和y
customer=vertexs(2:end,:);                                      %顾客坐标
cusnum=size(customer,1);                                        %顾客数
v_num=5;                                                        %车辆最多使用数目
demands=c101(2:end,4);                                          %需求量
a=c101(2:end,5);                                                %顾客时间窗开始时间[a[i],b[i]]
b=c101(2:end,6);                                                %顾客时间窗结束时间[a[i],b[i]]
s=c101(2:end,7);                                                %客户点的服务时间
h=pdist(vertexs);
dist=squareform(h);                                             %距离矩阵
%% 模拟退火参数
belta=10;                           %违反的容量约束的惩罚函数系数
gama=100;                           %违反时间窗约束的惩罚函数系数
MaxOutIter=1000;                    %外层循环最大迭代次数
MaxInIter=300;                      %里层循环最大迭代次数
T0=100;                             %初始温度
alpha=0.99;                         %冷却因子
pSwap=0.2;                          %选择交换结构的概率
pReversion=0.5;                     %选择逆转结构的概率
pInsertion=1-pSwap-pReversion;      %选择插入结构的概率
N=cusnum+v_num-1;                   %解长度=顾客数目+车辆最多使用数目-1
%% 随机构造初始解
currS=randperm(N);                  %随机构造初始解
[currVC,NV,TD,violate_num,violate_cus]=decode(currS,cusnum,cap,demands,a,b,L,s,dist);   %对初始解解码
%求初始配送方案的成本=车辆行驶总成本+belta*违反的容量约束之和+gama*违反时间窗约束之和
currCost=costFuction(currVC,a,b,s,L,dist,demands,cap,belta,gama);      
Sbest=currS;                        %初始将全局最优解赋值为初始解
bestVC=currVC;                      %初始将全局最优配送方案赋值为初始配送方案
bestCost=currCost;                  %初始将全局最优解的总成本赋值为初始解总成本
BestCost=zeros(MaxOutIter,1);       %记录每一代全局最优解的总成本
T=T0;                               %温度初始化
%% 模拟退火
for outIter=1:MaxOutIter
    for inIter=1:MaxInIter
        newS=Neighbor(currS,pSwap,pReversion,pInsertion);           %经过邻域结构后产生的新的解
        %对新解解码=车辆行驶总成本+belta*违反的容量约束之和+gama*违反时间窗约束之和
        newVC=decode(newS,cusnum,cap,demands,a,b,L,s,dist);         
        newCost=costFuction(newVC,a,b,s,L,dist,demands,cap,belta,gama);   %求初始配送方案的成本
        %如果新解比当前解更好,则更新当前解,以及当前解的总成本
        if newCost<=currCost 
            currS=newS; 
            currVC=newVC;
            currCost=newCost;
        else 
            %如果新解不如当前解好,则采用退火准则,以一定概率接受新解
            delta=(newCost-currCost)/currCost;           %计算新解与当前解总成本相差的百分比
            P=exp(-delta/T);                    %计算接受新解的概率
            %如果0~1的随机数小于P,则接受新解,并更新当前解,以及当前解总成本
            if rand<=P
                currS=newS; 
                currVC=newVC;
                currCost=newCost;
            end
        end
        %将当前解与全局最优解进行比较,如果当前解更好,则更新全局最优解,以及全局最优解总成本
        if currCost<=bestCost
            Sbest=currS;
            bestVC=currVC;
            bestCost=currCost;
        end
    end
    %% 解码
%输入:chrom               个体
%输入:cusnum              顾客数目
%输入:cap                 最大载重量
%输入:demands             需求量
%输入:a                   顾客时间窗开始时间[a[i],b[i]]
%输入:b                   顾客时间窗结束时间[a[i],b[i]]
%输入:L                   配送中心时间窗结束时间
%输入:s                   客户点的服务时间
%输入:dist                距离矩阵,满足三角关系,暂用距离表示花费c[i][j]=dist[i][j]
%输出:VC                  每辆车所经过的顾客,是一个cell数组
%输出:NV                  车辆使用数目
%输出:TD                  车辆行驶总距离
%输出:violate_num         违反约束路径数目
%输出:violate_cus         违反约束顾客数目
function [VC,NV,TD,violate_num,violate_cus]=decode(chrom,cusnum,cap,demands,a,b,L,s,dist)
violate_num=0;                                      %违反约束路径数目
violate_cus=0;                                      %违反约束顾客数目
VC=cell(cusnum,1);                                  %每辆车所经过的顾客
count=1;                                            %车辆计数器,表示当前车辆使用数目
location0=find(chrom>cusnum);                       %找出个体中配送中心的位置
for i=1:length(location0)
    if i==1                                         %第1个配送中心的位置
        route=chrom(1:location0(i));                %提取两个配送中心之间的路径
        route(route==chrom(location0(i)))=[];       %删除路径中配送中心序号
    else
        route=chrom(location0(i-1):location0(i));   %提取两个配送中心之间的路径
        route(route==chrom(location0(i-1)))=[];     %删除路径中配送中心序号
        route(route==chrom(location0(i)))=[];       %删除路径中配送中心序号
    end
    VC{count}=route;                                %更新配送方案
    count=count+1;                                  %车辆使用数目
end

三、运行结果

【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】
【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】
【TWVRP】基于matlab灰狼算法求解带时间窗的路径规划问题【含Matlab源码 1075期】

四、备注

版本:2014a

上一篇:三郎前端特效学习源代码:图片主页轮播组件


下一篇:作为程序员中的绅士,这10个技巧会让你的代码更加优雅