【TWVRP】基于matalb蚁群算法求解带时间窗的车辆路径规划问题【含Matlab源码 1406期】

1,191 阅读8分钟

一、VRP简介

1 VRP基本原理 车辆路径规划问题(Vehicle Routing Problem,VRP)是运筹学里重要的研究问题之一。VRP关注有一个供货商与K个销售点的路径规划的情况,可以简述为:对一系列发货点和收货点,组织调用一定的车辆,安排适当的行车路线,使车辆有序地通过它们,在满足指定的约束条件下(例如:货物的需求量与发货量,交发货时间,车辆容量限制,行驶里程限制,行驶时间限制等),力争实现一定的目标(如车辆空驶总里程最短,运输总费用最低,车辆按一定时间到达,使用的车辆数最小等)。 VRP的图例如下所示: 在这里插入图片描述 2 问题属性与常见问题 车辆路径问题的特性比较复杂,总的来说包含四个方面的属性: (1)地址特性包括:车场数目、需求类型、作业要求。 (2)车辆特性包括:车辆数量、载重量约束、可运载品种约束、运行路线约束、工作时间约束。 (3)问题的其他特性。 (4)目标函数可能是总成本极小化,或者极小化最大作业成本,或者最大化准时作业。

3 常见问题有以下几类: (1)旅行商问题 (2)带容量约束的车辆路线问题(CVRP) 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 该模型很难拓展到VRP的其他场景,并且不知道具体车辆的执行路径,因此对其模型继续改进。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 (3)带时间窗的车辆路线问题 由于VRP问题的持续发展,考虑需求点对于车辆到达的时间有所要求之下,在车辆途程问题之中加入时窗的限制,便成为带时间窗车辆路径问题(VRP with Time Windows, VRPTW)。带时间窗车辆路径问题(VRPTW)是在VRP上加上了客户的被访问的时间窗约束。在VRPTW问题中,除了行驶成本之外, 成本函数还要包括由于早到某个客户而引起的等待时间和客户需要的服务时间。在VRPTW中,车辆除了要满足VRP问题的限制之外,还必须要满足需求点的时窗限制,而需求点的时窗限制可以分为两种,一种是硬时窗(Hard Time Window),硬时窗要求车辆必须要在时窗内到达,早到必须等待,而迟到则拒收;另一种是软时窗(Soft Time Window),不一定要在时窗内到达,但是在时窗之外到达必须要处罚,以处罚替代等待与拒收是软时窗与硬时窗最大的不同。 在这里插入图片描述 在这里插入图片描述 模型2(参考2017 A generalized formulation for vehicle routing problems): 该模型为2维决策变量 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 (4)收集和分发问题 (5)多车场车辆路线问题 参考(2005 lim,多车场车辆路径问题的遗传算法_邹彤, 1996 renaud) 在这里插入图片描述 由于车辆是同质的,这里的建模在变量中没有加入车辆的维度。 在这里插入图片描述 在这里插入图片描述 (6)优先约束车辆路线问题 (7)相容性约束车辆路线问题 (8)随机需求车辆路线问题

4 解决方案 (1)数学解析法 (2)人机交互法 (3)先分组再排路线法 (4)先排路线再分组法 (5)节省或插入法 (6)改善或交换法 (7)数学规划近似法 (8)启发式算法

5 VRP与VRPTW对比 在这里插入图片描述

二、蚁群算法简介

1 蚁群算法(ant colony algorithm,ACA)起源和发展历程 Marco Dorigo等人在研究新型算法的过程中,发现蚁群在寻找食物时,通过分泌一种称为信息素的生物激素交流觅食信息从而能快速的找到目标,于是在1991年在其博士论文中首次系统地提出一种基于蚂蚁种群的新型智能优化算法“蚂蚁系统(Ant system,简称AS)”,后来,提出者及许多研究者对该算法作了各种改进,将其应用于更为广泛的领域,如图着色问题、二次分配问题、工件排序问题、车辆路径问题、车间作业调度问题、网络路由问题、大规模集成电路设计等。近些年来,M.Dorigo等人把蚂蚁算法进一步发展成一种通用的优化技术“蚁群优化(Ant Colony Optimization,简称ACO)”,并将所有符合ACO框架的算法称为“蚁群优化算法(ACO algorithm)”。

在这里插入图片描述 具体来说,各个蚂蚁在没有事先告知食物在什么地方的前提下开始寻找食物。当一只找到食物以后,它会向环境释放一种挥发性分泌物pheromone (称为信息素,该物质随着时间的推移会逐渐挥发消失,信息素浓度的大小表征路径的远近)信息素能够让其他蚂蚁感知从而起到一个引导的作用。通常多个路径上均有信息素时,蚂蚁会优先选择信息素浓度高的路径,从而使浓度高的路径信息素浓度更高,形成一个正反馈。有些蚂蚁并没有像其它蚂蚁一样总重复同样的路,他们会另辟蹊径,如果另开辟的道路比原来的其他道路更短,那么,渐渐地,更多的蚂蚁被吸引到这条较短的路上来。最后,经过一段时间运行,可能会出现一条最短的路径被大多数蚂蚁重复着。最终,信息素浓度最高的路径即是最终被蚂蚁选中的最优路径。 与其他算法相比,蚁群算法是一种比较年轻的算法,具有分布式计算、无中心控制、个体之间异步间接通信等特点,并且易于与其他优化算法相结合,经过不少仁人志士的不断探索,到今天已经发展出了各式各样的改进蚁群算法,不过蚁群算法的原理仍是主干。

2 蚁群算法的求解原理 基于上述对蚁群觅食行为的描述,该算法主要对觅食行为进行以下几个方面模拟: (1)模拟的图场景中包含了两种信息素,一种表示家,一种表示食物的地点,并且这两种信息素都在以一定的速率进行挥发。 (2)每个蚂蚁只能感知它周围的小部分地方的信息。蚂蚁在寻找食物的时候,如果在感知范围内,就可以直接过去,如果不在感知范围内,就要朝着信息素多的地方走,蚂蚁可以有一个小概率不往信息素多的地方走,而另辟蹊径,这个小概率事件很重要,代表了一种找路的创新,对于找到更优的解很重要。 (3)蚂蚁回窝的规则与找食物的规则相同。 (4)蚂蚁在移动时候首先会根据信息素的指引,如果没有信息素的指引,会按照自己的移动方向惯性走下去,但也有一定的机率改变方向,蚂蚁还可以记住已经走过的路,避免重复走一个地方。 (5)蚂蚁在找到食物时留下的信息素最多,然后距离食物越远的地方留下的信息素越少。找到窝的信息素留下的量的规则跟食物相同。蚁群算法有以下几个特点:正反馈算法、并发性算法、较强的鲁棒性、概率型全局搜索、不依赖严格的数学性质、搜索时间长,易出现停止现象。 蚂蚁转移概率公式: 在这里插入图片描述 公式中:是蚂蚁k从城市i转移到j的概率;α,β分别为信息素和启发式因子的相对重要程度;为边(i,j)上的信息素量;为启发式因子;为蚂蚁k下步允许选择的城市。上述公式即为蚂蚁系统中的信息素更新公式,是边(i,j)上的信息素量;ρ是信息素蒸发系数,0<ρ<1;为第k只蚂蚁在本次迭代中留在边(i,j)上的信息素量;Q为一正常系数;为第k只蚂蚁在本次周游中的路径长度。 在蚂蚁系统中,信息素更新公式为: 在这里插入图片描述 3 蚁群算法的求解步骤: (1)初始化参数在计算之初,需要对相关参数进行初始化,如蚁群规模(蚂蚁数量)m、信息素重要程度因子α、启发函数重要程度因子β、信息素会发银子ρ、信息素释放总量Q、最大迭代次数iter_max、迭代次数初值iter=1。 (2)构建解空间将各个蚂蚁随机地置于不同的出发点,对每个蚂蚁k(k=1,2,3…m),按照(2-1)计算其下一个待访问城市,直到所有蚂蚁访问完所有城市。 (3)更新信息苏计算每个蚂蚁经过路径长度Lk(k=1,2,…,m),记录当前迭代次数中的最优解(最短路径)。同时,根据式(2-2)和(2-3)对各个城市连接路径上信息素浓度进行更新。 (4) 判断是否终止若iter<iter_max,则令iter=iter+1,清空蚂蚁经过路径的记录表,并返回步骤2;否则,终止计算,输出最优解。 (5)判断是否终止若iter<iter_max,则令iter=iter+1,清空蚂蚁经过路径的记录表,并返回步骤2;否则,终止计算,输出最优解。3. 判断是否终止若iter<iter_max,则令iter=iter+1,清空蚂蚁经过路径的记录表,并返回步骤2;否则,终止计算,输出最优解。

在这里插入图片描述

三、部分源代码

clear; clc; close all;
tic
%% input 
c101 = importdata('c101.txt');
% c101 = importdata('my_test_data.xlsx');
% depot_time_window1 = c101(1,5); % time window of depot
% depot_time_window2 = c101(1,6);

depot_time_window1 = TimeTrans(c101(1,5)); % time window of depot
depot_time_window2 = TimeTrans(c101(1,6));
vertexs = c101(:,2:3); 
customer = vertexs(2:end,:); % customer locations
customer_number = size(customer,1);
% vehicle_number = 25;
% time_window1 = c101(2:end,5);
% time_window2 = c101(2:end,6);

time_window1 = TimeTrans(c101(2:end,5));
time_window2 = TimeTrans(c101(2:end,6));

width = time_window2-time_window1; % width of time window
service_time = c101(2:end,7); 
h = pdist(vertexs);
dist = squareform(h); % distance matrix
%% initialize the parameters
ant_number = floor(customer_number * 1.5);                                                  % number of ants
alpha = 4;                                                        % parameter for pheromone
beta = 5;                                                         % paremeter for heuristic information
gamma = 2;                                                        % parameter for waiting time
delta = 3;                                                        % parameter for width of time window
r0 = 0.5;                                                         % a constant to control the movement of ants
rho = 0.85;                                                       % pheromone evaporation rate
Q = 5;                                                            % a constant to influence the update of pheromene
Eta = 1./dist;                                                    % heuristic function
iter = 1;                                                         % initial iteration number
iter_max = 200;                                                    % maximum iteration number

Tau = ones(customer_number+1,customer_number+1);                  % a matrix to store pheromone
Table = zeros(ant_number,customer_number);                        % a matrix to save the route
Route_best = zeros(iter_max,customer_number);                     % the best route
Cost_best = zeros(iter_max,1);                                    % the cost of best route



iter_time = [];
last_dist = 0;
stop_count = 0;



%% find the best route 
while iter <= iter_max
    %tic;
    % ConstructAntSolutions
    for i = 1:ant_number
        for j = 1:customer_number
            r = rand;
            np = NextPoint(i,Table,Tau,Eta,alpha,beta,gamma,delta,r,r0,time_window1,time_window2,width,service_time,depot_time_window2,dist);
            Table(i,j) = np;
        end
    end
    %% calculate the cost for each ant
    cost = zeros(ant_number,1);
    NV = zeros(ant_number,1);
    TD = zeros(ant_number,1);
    for i=1:ant_number
        VC = decode(Table(i,:),time_window1,time_window2,depot_time_window2,service_time,dist);
        [cost(i,1),NV(i,1),TD(i,1)] = CostFun(VC,dist);
    end
    %% find the minimal cost and the best route
    if iter == 1
        [min_Cost,min_index] = min(cost);
        Cost_best(iter) = min_Cost;
        Route_best(iter,:) = Table(min_index,:);
    else
        % compare the min_cost in this iteration with the last iter
        [min_Cost,min_index] = min(cost);
        Cost_best(iter) = min(Cost_best(iter - 1),min_Cost); 
        if Cost_best(iter) == min_Cost
            Route_best(iter,:) = Table(min_index,:);
        else
            Route_best(iter,:) = Route_best((iter-1),:);
        end
    end
    %% update the pheromene
    bestR = Route_best(iter,:); % find out the best route
    [bestVC,bestNV,bestTD] = decode(bestR,time_window1,time_window2,depot_time_window2,service_time,dist); 
    Tau = updateTau(Tau,bestR,rho,Q,time_window1,time_window2,depot_time_window2,service_time,dist);

    %% print 
    disp(['Iterration: ',num2str(iter)])
    disp(['Number of Robots: ',num2str(bestNV),', Total Distance: ',num2str(bestTD)]);
    fprintf('\n')
    %
    iter = iter+1;
    Table = zeros(ant_number,customer_number);
    
    %iter_time(iter) = toc;
    
%     if last_dist == bestTD
%         stop_count = stop_count + 1;
%         if stop_count > 30
%             break;
%         end
%     else
%         last_dist = bestTD;
%         stop_count = 0;
%     end
    
end
%% draw
bestRoute=Route_best(iter-1,:);
[bestVC,NV,TD]=decode(bestRoute,time_window1,time_window2,depot_time_window2,service_time,dist);
draw_Best(bestVC,vertexs);
figure(2)
plot(1:iter_max,Cost_best,'b')
xlabel('Iteration')
ylabel('Cost')
title('Change of Cost')
%% check the constraints, 1 == no violation
flag = Check(bestVC,time_window1,time_window2,depot_time_window2,service_time,dist)

toc

function draw_Best(VC,vertexs)
customer=vertexs(2:end,:);  
NV=size(VC,1); 
figure
hold on;box on
title('Map of Best Solution')
hold on;
C=linspecer(NV);
for i=1:NV
    part_seq=VC{i};
    len=length(part_seq);
    for j=0:len
        if j==0
            fprintf('%s','Route',num2str(i),':');
            fprintf('%d->',0);
            c1=customer(part_seq(1),:);
            plot([vertexs(1,1),c1(1)],[vertexs(1,2),c1(2)],'-','color',C(i,:),'linewidth',1);
        elseif j==len
            fprintf('%d->',part_seq(j));
            fprintf('%d',0);
            fprintf('\n');
            c_len=customer(part_seq(len),:);
            plot([c_len(1),vertexs(1,1)],[c_len(2),vertexs(1,2)],'-','color',C(i,:),'linewidth',1);
        else
            fprintf('%d->',part_seq(j));
            c_pre=customer(part_seq(j),:);
            c_lastone=customer(part_seq(j+1),:);
            plot([c_pre(1),c_lastone(1)],[c_pre(2),c_lastone(2)],'-','color',C(i,:),'linewidth',1);
        end
    end
end
plot(customer(:,1),customer(:,2),'ro','linewidth',1);hold on;
plot(vertexs(1,1),vertexs(1,2),'s','linewidth',2,'MarkerEdgeColor','b','MarkerFaceColor','b','MarkerSize',10);
end

四、运行结果

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

五、matlab版本及参考文献

1 matlab版本 2014a

2 参考文献 [1] 包子阳,余继周,杨杉.智能优化算法及其MATLAB实例(第2版)[M].电子工业出版社,2016. [2]张岩,吴水根.MATLAB优化算法源代码[M].清华大学出版社,2017.