蚁群算法求解有时间窗约束的车辆路径问题matlab程序
1 简介
带时间窗的车辆路径问题(VRPTW)一般描述为从某一物流配送中心出发,用多台车辆向多个顾客送货,车辆完成配送任务后返回配送中心。 已知每个顾客的位置与需求量, 每台车的容量一定, 将货物送到顾客手中需要满足一定的时间约束, 要求合理安排行车路线使目标函数得到优化。 对该问题的研究引起了广大学者的关注。 它是有容量约束车辆路径问题的扩展, 是NP难题, 求解算法可分为精确算法与启发式算法。当顾客点数目较多时, 使用精确算法很难在可接受的时间内求得全局最优解, 因此, 用启发式算法在可接受的时间内求得问题的满意解成为研究的重要方向。
蚁群算法是由Dorigo等首先提出来的, 它的基本思想是利用一群人工蚂蚁的协作来寻找优化问题的较优解, 每只蚂蚁根据问题所给的准则, 从被选中的初始状态出发建立一个可行解或部分解, 各个蚂蚁间通过信息素交换信息, 从而达到相互协作的目的。蚁群算法的思想已被应用到各个研究领域, 并取得了大量的研究成果, 而在VRPTW方面的研究则较少。
2 有时间窗的车辆路径问题
为简化问题的描述,需要在构建模型前做一些基本的假设和约束:
(1) 假设物流运输车辆状况相同;
(2) 单车运载力要大于单个客户需求量,且每条路线上的客户需求总量不大于单车最大运载力;
(3) 配送中心能够满足所有客户需求,无缺货;
(4) 车辆完成配送后直接返回配送中心;
(5) 每条路径长度不超过单车最大行程;
(6) 车辆要在时间窗内到达相应客户点,否则会产生惩罚成本;
向客户配送货物有时间限制,在此采用软时间窗的限制方法进行处理, 即对客户需求的货物在一定的时间范围内到达,若未能按时到达,则将对物流配送企业给予一定的罚金。则因不在时间窗内将产品送到客户点而产生的处罚成本用C5表示,公式如下所示:
其中:分别表示车辆早于和晚于时间窗将货物卸下而带来的损失成本。为车辆到达客户 j 的时刻,为车辆在客户 j 处等待的时间。
3 问题求解
蚁群算法(Ant Colony Algorithm)可以很好地解决 VRP,因为该算法在满足各需求点的时间窗约束的前提下采用动态信息策略, 以保证在每次搜索中每只蚂蚁都对搜索做出贡献,
最快地找到最优解或满意解。简单来说,此算法是一种源于自然界中生物世界新的仿生类随机型、智能多主体搜索算法,它吸收了昆虫王国中蚂蚁的行为特性,通过其内在的搜索机制,在一系列困难的路径优化问题求解中取得了成效。所以本文打算通过 MATLAB 强大的计算功能编写蚁群算法程序来深入研究冷链物流路径优化问题。
基本蚁群算法的思路如下:
Begin
初始化:
Nc 0;(Nc为迭代次数)
对各边弧(i,j);
常数c;(较小的正数) 0;
Ca L;(ca为车辆的剩余载重量)
Cb N;(Cb为车辆的剩余行驶距离)
读入其他输入参数;
Loop:
将初始点放入当前的解集中;
While(不满足停机准则)do
begin
对每只蚂蚁k;
按照剩余载重量,剩余行驶路径长和转移概率选择顶点j;
将蚂蚁k从顶点i转移到顶点j;
将顶点i放在当前的解集中;
end
当所有的城市都放在解集中,就记录蚂蚁的个数M k;
利用局部搜索机制来优化路径;
然后计算每只蚂蚁的目标函数值;
并计算当前的最好解;
For k 1toM do
begin
对各边(i,j),计算:;(增加的信息素)
end
对各边(i,j),计算:;(轨迹更新)
对各边(i,j),置;
;
若Nc<预定的迭代次数,则go to Loop;
End
部分程序
% Author: 怡宝2号 博士猿工作室
% Use: 用蚁群算法求解有容量限制、时间窗限制的车辆路径问题;
% 坐标视自己的具体情况而定。
% Illustrate:输入变量(must):
% coordinate:要求的相应点的坐标,第一行是点的横坐标,第二行是点的纵坐标
% demand(1*n),n表示工厂的个数;t表示各个工厂要求运送的货物的重量
% LimitW:每辆车限制的载重量
% Can—changed parameter: m:蚁群的规模
% MAXGEN:蚁群的最大迭代代数
%
% 输出: bestpop:最短路程对应的路径
% trace :最短路程
% remark: 如有疑问请咨询qq:778961303
clc
clear all
close all
format compact
%蚁群参数初始化
Alpha = 1; %求解选择下一个城市的概率
Beta = 5; %求解选择下一个城市的概率
Rho = 0.75; %信息素的全局更新
Q = 200; %信息素增加强度系数
Elite = 1; %精英蚂蚁数量
m = 40; %每一代有40只蚂蚁
MAXGEN = 100; %最大迭代代数
Prab = 0.05; %伪随机选择概率
%读取初始数据,初始化成本函数的参数
[F,C,P,ZETA1,ZETA2,THETA,R,S,ELTAT,COSTP,V,BETA,OMEGA1,OMEGA2,coordinate,demand,ET,LT,ST,speed, LimitW] = initial();
%求各个客户点之间的距离
[Distance n] = CalculateD(coordinate); %n为客户数量,包括配送中心
Eta=1./Distance; %Eta为启发因子,离散模型设为距离的倒数
Tau=ones(n,n); %Tau为信息素矩阵,行:前一个城市的标号;列:后一个城市的标号。
Tabu=zeros(m,n+20); %存储并记录路径的生成
bestpop = zeros(MAXGEN,n+20); %每代最优的蚂蚁
trace = zeros(MAXGEN,1); %每代最小的成本
%迭代寻优开始开始
load = 0; %初始化载重
NC=1; %迭代计数器
while NC<=MAXGEN
Tabu(:,1)=1; %每只蚂蚁都是从仓库(及节点1)开始出发
%精英保留策略
start = 1;
if 2<=NC
start = Elite + 1;
end
for i=start:m
visited=Tabu(i,:);
visited=visited(visited>0);
to_visit=setdiff(1:n,visited); %在集合论中,to_visit = (1:n) - visited
actualST = zeros(n,1); %实际服务时间,初始化,一只蚂蚁初始化一次
actualST(1) = ET(1); %对初始点的服务时间,初始化
j=1;
while j<=n
if ~isempty(to_visit) %判断所有客户点是否送完
%计算接下来要参观的其他城市的概率
for k=1:length(to_visit)
[Tij actualST] = CalculateT( visited(end) , to_visit(k) ,actualST,Distance,ST,speed); %计算从客户i到达客户j的时间
VC = CalculateVC( visited(end) , to_visit , actualST , Distance , ST, speed, LT); %计算从客户i到下一个客户的潜在客户
x(k)=(Tau(visited(end),to_visit(k))^Alpha)*(Eta(visited(end),to_visit(k))^Beta)*...
1/( abs(Tij-ET(to_visit(k))) + abs(Tij-LT(to_visit(k))) )*VC;
end
%伪随机选择,选择下一个城市
temp_pra=rand;
if temp_pra=rand);
end
%计算车的载重
if isempty(Select) %如果选不了下一个城市了,就回到1点
Select=1;
load=load+demand(Select); %select=1;t(select)=0
else
load=load+demand(to_visit(Select(1))); %select表示城市标号,to_visit(select)才表示城市
end
%判断载重是否超限,并对路径表修改
if load>W %判断车是否超载,超载就回到原地
Select=1;
j=j-1; %j表示参观了的城市,参观的城市-1
load=0; %车辆的载重归零
Tabu(i,length(visited)+1)=Select(1); %给车辆的路径信息赋值,及回到原点,要参观的客户赋值为1.
else
Tabu(i,length(visited)+1)=to_visit(Select(1));
end
end
%对访问过的客户,和待访问的客户初始化
visited=Tabu(i,:);
visited=visited(visited>0); %已经拜访过的客户
to_visit=setdiff(1:n,visited);
x=[];
if visited(end)~=1
Tabu(i,1:(length(visited)+1))=[visited,1];
end
j = j+1;
j;
end
%1只蚂蚁配送路线完成
load = 0;
end
%m只蚂蚁路线安排完成
%计算m只蚂蚁的个体适应度
L=zeros(m,1); %共有m只蚂蚁
for i=1:m
temp=Tabu(i,:);
route=temp(temp>0); %每只蚂蚁的路径
end
%精英保留策略
[ex index] = sort(L,'ascend');
index = index(1:Elite);
temp = Tabu(index,:);
tempL = L(index);
Tabu(1:Elite,:) = temp;
L(1:Elite) = tempL;
[mintrace index] = min(L); %最小的成本
temp = Tabu(index(1),:); %最小成本对应的蚂蚁
trace(NC) = mintrace; %保存每代的最小成本和最小蚂蚁
bestpop(NC,:) = temp;
%更新信息素
Delta_Tau=zeros(n,n);
for i=1:m
temp=Tabu(i,:);
route=temp(temp>0);
for j=1:(length(route)-1)
Delta_Tau(route(j),route(j+1))=Delta_Tau(route(j),route(j+1))+Q/L(i);
end
Delta_Tau(route(n),route(1))=Delta_Tau(route(n),route(1))+Q/L(i);
end
% %信息素更新
% Delta_Tau=zeros(n,n);
% for i=1:m
% temp=Tabu(i,:);
% route=temp(temp>0);
% for j=1:(length(route)-1)
% Delta_Tau(route(j),route(j+1))=Delta_Tau(route(j),route(j+1))+Q/L(i);
% end
% end
% Tau=(1-Rho).*Tau+Delta_Tau;
%路径清零,载荷清零
temp=zeros(m-Elite,n+20);
Tabu(Elite+1:m,:) = temp;
load=0;
disp(['共迭代',num2str(MAXGEN),'次,现在为:',num2str(NC)]);
% NC
NC = NC + 1;
end
%绘制寻优迭代图
figure()
plot(trace)
plot(trace,'--b',...
'LineWidth',2);
grid off
xlabel('迭代次数数')
ylabel('成本')
title('成本变化','fontsize',16)
%显示路径
[mintrace index] = min(trace); %最小成本
route = bestpop(index,:); %最小成本的路径
route = route( route>0 );
p=num2str(route(1));
for i=2:length(route)
p=[p,'->',num2str(route(i))];
end
display(['求解的最优路径为:',num2str(p)]);
display(['1代表物流中心']);
disp(['最小的成本代价为:',num2str(min(trace))]);
%绘制最小成本的路径
figure();
DrawRoute(coordinate,route)
% remark: 如有疑问请咨询qq:778961303