一、原理简介

蚁群算法的基本原理

1、蚂蚁在路径上释放信息素。

2、碰到还没走过的路口,就随机挑选一条路走。同时,释放与路径长度有关的信息素。

3、信息素浓度与路径长度成反比。后来的蚂蚁再次碰到该路口时,就选择信息素浓度较高路径。

4、最优路径上的信息素浓度越来越大。

5、最终蚁群找到最优寻食路径。

 【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划

 

 蚁群走过较短的那一侧的蚂蚁数数量会多于较长那一侧的,所以留下的信息素就会多,渐渐的蚂蚁就只走较短的那一侧了。

 

蚁群算法对TSP的求解主要有两大步骤:(TSP问题就是要找到最短哈密尔顿回路)

1、路径构建

AS中的随机比例规则;对于每只蚂蚁k,路径记忆向量R^k.按照访问顺序记录了所有k已经经过的城市序号。设蚂蚁k当前所在城市为i,则其选择城市j作为下一个访问对象的概率为:

【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划_02

 

 

2、信息素更新

 【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划_03

这里m是蚂蚁个数, ρ是信息素的蒸发率,规定0≤ ρ≤1,在AS中通常设置为 ρ =0.5,Δτij是第k只蚂蚁在它经过的边上释放的信息素量,它等于蚂蚁k本轮构建路径长度的倒数。C^k表示路径长度,它是R^k中所有边的长度和。

构建图:构建图与问题描述图是一致的,成份的集合C对应着点的集合(即:C=N),连接对应着边的集合(即L=A),且每一条边都带有一个权值,代表点i和j之间的距离。

约束条件:所有城市都要被访问且每个城市最多只能被访问一次。

信息素和启发式信息:TSP 问题中的信息素表示在访问城市i后直接访问城市j的期望度。启发式信息值一般与城市i和城市j的距离成反比。

解的构建:每只蚂蚁最初都从随机选择出来的城市出发,每经过一次迭代蚂蚁就向解中添加一个还没有访问过的城市。当所有城市都被蚂蚁访问过之后,解的构建就终止。

 

【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划_04

 

 

蚁群算法存在缺陷

蚁群算法在解决小规模TSP问题是勉强能用,稍加时间就能发现最优解,但是若问题规模很大,蚁群算法的性能会极低,甚至卡死。所以可以进行改进,例如精英蚂蚁系统。

精英蚂蚁系统是对基础蚁群算法的一次改进,它在原AS信息素更新原则的基础上增加了一个对至今最优路径的强化手段。在每轮信息素更新完毕后,搜索到至今最优路径的那只蚂蚁将会为这条路径添加额外的信息素。精英蚂蚁系统引入 这种额外的信息素强化手段有助于更好的引导蚂蚁搜索的偏向,使算法更快收敛

【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_matlab_05

 

二、实例及代码

【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划_06

Excel  exp12_3_2.xls内容:

【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划_07

 

function []=antvrptwwithjamminallcost()clear all; %清除所有变量  close all; %清图  clc ;      %清屏  tic%开始计时。考虑拥堵时间段,以总费用作为比较目标%%SOLOMON问题数据 wenjian=textread('RXx201.txt');%%调用文件 changdu=size(wenjian,1);%%调用文件的长度 city_coordinate=zeros(changdu,2);%%需求点坐标 demands=zeros(1,changdu);%%需求 earlytime=zeros(1,changdu);%%需求点时间最早服务限制 windowtime=zeros(1,changdu);%%需求点时间限制 servicetime=zeros(1,changdu);%服务时间  for i=1:changdu     city_coordinate(i,1)=(wenjian(i,2));%坐标 city_coordinate(i,2)=(wenjian(i,3));%坐标demands(i)=(wenjian(i,4));%需求量earlytime(i)=10;%(wenjian(i,5))-30;%时间限制,最早时间窗windowtime(i)=(wenjian(i,6))+60;%时间限制servicetime(i)=(wenjian(i,7));%服务时间 end  % city_coordinate %需求点坐标% demands%需求量% earlytime%%需求点时间最早服务限制% windowtime%时间窗限制% servicetime%服务时间 % city_coordinate=[42,59;6,17;37,19;22,76;28,11;21,16;12,65;35,18;38,29];%坐标           % demands=[0,90,40,60,70,70,40,20,40];%需求量% windowtime=[0,100,200,300,300,300,300,300,300];%时间窗限制% earlytime=[0,20,40,230,110,220,40,220,40];%服务时间% servicetime=[0,20,40,30,10,20,40,20,40];%服务时间 %%初始化变量m=40;% m 蚂蚁个数NC_max=10;% 最大允许运行次数Alpha=1;% Alpha 表征信息素重要程度的参数Beta=3;% Beta 表征启发式因子重要程度的参数Rho=0.25;% Rho 信息素蒸发系数Q=20;% Q 信息素增加强度系数vehiclecapacity=200;%车辆容量C=city_coordinate;n=size(C,1);%n需求点个数%%计算节点之间的距离D=zeros(n,n);%D距离矩阵 for i=1:n    for j=1:n      if i~=j          D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;      else         D(i,j)=eps;      end     D(j,i)=D(i,j);    endend D;%距离矩阵 %%carspeed=60;%运输车辆正常行驶速度jamcarspeed=20;%拥堵时段的车辆行驶速度load_w=0;%车辆载重Eta=1./D;% %Eta为启发因子矩阵,这里设为距离的倒数Tau=ones(n,n);%%Tau为信息素矩阵Tabu=zeros(m,n);%存储并记录路径的生成,禁忌表NC=1;%当前运行次数G_best_route=[NC_max,n*2];%各代最佳路线G_best_length=inf.*ones(1,NC_max);%%各代最佳路线的长度length_ave=zeros(1,NC_max);%%各代路线的平均长度%iterbestlength=zeros(1,NC_max);%每次迭代最优距离的长度dividelength=2;%道路分阶段的长度%%定义计算碳排放的变量bestfuelconsumptionofcar=0;%该车辆的碳排放量;iterbestroute=zeros(1,n*2);%各代最佳路线dangqianroute=zeros(1,n*2);%当前的各代最佳路线bestroute=zeros(1,n*2);%最佳路线bestjuli=0;%最佳路线长度bijiaomubiao=0;%每次的比较目标minmubiao=0;qiyoujiage=7.5;%汽油价格fixfeeofvehicle=200;%汽车固定使用费用varityfeeofvehicle=2;%汽车变动使用费用:单位:元/单位距离carbonunitoffuel=2.32;%每升汽油的碳排放标准,单位:公斤unitcarbonfee=0.0528;%每公斤碳的收费价格renlifeeunit=0.5;%每分钟的人力资源成本besttravletime=0;%所有服务车辆的行驶时间bestcarfee=0;%所有服务车辆的费用,车辆固定费用+变动使用费用+人力成本bestcarbon=0;%%所有服务车辆的碳排放数量bestqiyoufee=0;%%所有服务车辆的汽油费用 Delta_Tau=zeros(n,n);%%信息素矩阵 %% %停止条件之一:达到最大迭代次数,停止while NC<=NC_max%循环控制   %如randi(2,3,[1 6]),就是产生一个2*3随机矩阵,这个矩阵的元素是区间[1 6]的随机数。    Tabu(:,1)=randi(1,m,1);    factfuelconsumptionofcar=zeros(1,m);%每次只蚂蚁访问所有路径的所有油耗    totaltimeofvehicletravle=zeros(1,m);%每次只蚂蚁访问所有路径的所有时间    anttraveldistance=zeros(1,m);%每次只蚂蚁访问所有节点的距离        factantcarbon=zeros(1,m);%蚂蚁访问所有路径的视角产生的碳排放量    routejuli=0;%%路线距离     bestmubiao=0;%最优的比较目标%%m只蚂蚁的访问遍历情况 for i=1:m%     disp('===========新的蚂蚁开始访问============')%     disp('蚂蚁所用时间')%     totaltimeofvehicletravle(i)    visited=Tabu(i,:);%已经访问的需求点    visited=visited(visited>0);    to_visit=setdiff(1:n,visited);%比较2个数组内不同的值,得出还没有访问的需求点    %%蚂蚁开始访问         load_w=0;%%    vehicletime=0;%%车辆时间控制    dangqianvehiclevisittime=0;    carcarbon=0;%蚂蚁访问所有路径的可能产生的碳排放量    fuelconsumptionofcar=0;%蚂蚁访问所有路径的可能产生的油耗量    j=1;    while j<=n%         disp('访问当前节点的具体时间,新的节点')%         vehicletime     if ~isempty(to_visit)%如果还有没有访问的需求点          to_visit ;               %% 判断选择哪个需求点          for k=1:length(to_visit)%对每一个将要访问的需求点进行信息素计算            x(k)=(Tau(visited(end),to_visit(k))^Alpha)*(Eta(visited(end),to_visit(k))^Beta); %Tau为信息素矩阵,% Alpha 表征信息素重要程度的参数,%Eta为启发因子矩阵,这里设为距离的倒数,%% Beta 表征启发式因子重要程度的参数          end                    %%需求点选择方法           ww=rand;%随机生成一个概率           x=x/(sum(x));            xcum=cumsum(x);            Select=find(xcum>=ww);%若计算的概率大于原来的就选择这条路线%要选择其中总概率大于等于某一个随机数,找到大于等于这个随机数的需求点的在未访问需求点中的位置                    %%选择到的节点       %              disp('访问当前节点')%              to_visit(Select(1))            load_w=load_w+demands(to_visit(Select(1)));%车辆装载量计算            r=load_w/vehiclecapacity;%汽车载重与车辆容量的比例            Tabu(i,length(visited));%当前已经访问节点            to_visit(Select(1));%当前将要访问节点%             disp('访问当前节点的距离')%             D(Tabu(i,length(visited)),to_visit(Select(1)))%节点之间的距离                        %开始该路段的时间计算            pathlength=D(Tabu(i,length(visited)),to_visit(Select(1)));       %该路段长度            kk=ceil(pathlength/dividelength);%ceil表示向上取整,得出该路段分得的所有段数            currentcartime=zeros(1,kk);%%车辆行驶在路段K的当前行驶时间                        %%拥堵时间判断                        if kk==1 & dividelength>pathlength %第一个路段非常小                if (vehicletime>=60 & vehicletime<=120) || (vehicletime>=720 & vehicletime<=840)                   currentcartime(1)=(pathlength/jamcarspeed)*60;%拥堵时间段行驶的各个路段时间                   currentfuel(1)=pathlength*(0.0617*jamcarspeed*jamcarspeed-7.8227*jamcarspeed+429.51)/1000;%车辆油耗                   carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/jamcarspeed-1.33/jamcarspeed;                else                   currentcartime(1)=(pathlength/jamcarspeed)*60;%正常行驶的各个路段时间                   currentfuel(1)=pathlength*(0.0617*carspeed*carspeed-7.8227*carspeed+429.51)/1000;%车辆油耗                   carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/carspeed-1.33/carspeed;                end                vehicletime= vehicletime+currentcartime(1);                               fuelconsumptionofcar=fuelconsumptionofcar+currentfuel(1);                               carcarbon=carcarbon+currentfuel(1)*carbonxiuzhengbili*carbonunitoffuel;%%这只蚂蚁的碳排放量            else                    currentcartime(1)=(dividelength/carspeed)*60;%正常行驶的各个路段时间                vehicletime= vehicletime+currentcartime(1);                               currentfuel(1)=dividelength*(0.0617*carspeed*carspeed-7.8227*carspeed+429.51)/1000;%车辆油耗                fuelconsumptionofcar=fuelconsumptionofcar+currentfuel(1);                carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/carspeed-1.33/carspeed;                carcarbon=carcarbon+currentfuel(1)*carbonxiuzhengbili*carbonunitoffuel;%%这只蚂蚁的碳排放量            end                        for ii=2:kk%计算每一段路段的行驶速度与行驶时间                if ii<kk                if (vehicletime>=60 & vehicletime<=120) || (vehicletime>=720 & vehicletime<=840)                  currentcartime(ii)=dividelength/jamcarspeed*60;%正常时间段行驶的各个路段时间                  currentfuel(ii)=dividelength*(0.0617*jamcarspeed*jamcarspeed-7.8227*jamcarspeed+429.51)/1000;%车辆油耗                  carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/jamcarspeed-1.33/jamcarspeed;                else                  currentcartime(ii)=dividelength/carspeed*60;%正常时间段行驶的各个路段时间                  currentfuel(ii)=dividelength*(0.0617*carspeed*carspeed-7.8227*carspeed+429.51)/1000;%车辆油耗                  carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/carspeed-1.33/carspeed;                end                   vehicletime=vehicletime+currentcartime(ii);                                      fuelconsumptionofcar=fuelconsumptionofcar+currentfuel(ii);                                      carcarbon=carcarbon+currentfuel(ii)*carbonxiuzhengbili*carbonunitoffuel;%%这只蚂蚁的碳排放量                end                if (ii==kk)  %最后一个路段的各个路段时间                           if (vehicletime>=60 & vehicletime<=120) || (vehicletime>=720 & vehicletime<=840)                  currentcartime(ii)=dividelength/jamcarspeed*60;%正常时间段行驶的各个路段时间                  currentfuel(ii)=dividelength*(0.0617*jamcarspeed*jamcarspeed-7.8227*jamcarspeed+429.51)/1000;%车辆油耗                  carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/jamcarspeed-1.33/jamcarspeed;                else                  currentcartime(ii)=dividelength/carspeed*60;%正常时间段行驶的各个路段时间                  currentfuel(ii)=dividelength*(0.0617*carspeed*carspeed-7.8227*carspeed+429.51)/1000;%车辆油耗                  carbonxiuzhengbili=1.27+0.0614*r-0.0011*r*r-0.00235/carspeed-1.33/carspeed;                end                   vehicletime=vehicletime+currentcartime(ii);                                      fuelconsumptionofcar=fuelconsumptionofcar+currentfuel(ii);                                      carcarbon=carcarbon+currentfuel(ii)*carbonxiuzhengbili*carbonunitoffuel;%%这只蚂蚁的碳排放量                              end             end%             disp('+++++随机需求点:车辆行驶该路段的行驶时间')%            vehicletime          %                       vehicletime= vehicletime+servicetime(to_visit(Select(1))); %将要访问的需求点的服务时间计算 %            disp('车辆行驶该路段的行驶时间++加上服务时间')%            servicetime(to_visit(Select(1)))%             vehicletime             dangqianvehiclevisittime=dangqianvehiclevisittime+vehicletime;                                        %%%容量和时间判断            if (load_w<=vehiclecapacity && dangqianvehiclevisittime<=windowtime(to_visit(Select(1))) ) && dangqianvehiclevisittime>=earlytime(to_visit(Select(1)))            %if  dangqianvehiclevisittime<=windowtime(to_visit(Select(1))) && dangqianvehiclevisittime>=earlytime(to_visit(Select(1)))                    Tabu(i,length(visited)+1)=to_visit(Select(1)); %访问的节点                    totaltimeofvehicletravle(i)=totaltimeofvehicletravle(i)+vehicletime;%%蚂蚁i所有的车辆行驶时间%                     disp('+++++++++车辆的行驶时间之和+++++++++++++')%                     totaltimeofvehicletravle(i)                    anttraveldistance(i)=anttraveldistance(i)+pathlength;%%蚂蚁i所有车辆的行驶距离                    factantcarbon(i)=factantcarbon(i)+carcarbon;%%蚂蚁i所有车辆的实际产生的碳排放                    factfuelconsumptionofcar(i)=factfuelconsumptionofcar(i)+fuelconsumptionofcar;                    vehicletime=0;%服务时间归零                    fuelconsumptionofcar=0;                     carcarbon=0;                                else%                    disp('该车辆服务完毕的的行驶时间')%                    vehicletime                   j=j-1;%没有选择到需求点,因此循环计数器减少一次                   load_w=0;%车辆装载量归零                   vehicletime=0;%服务时间归零                   carcarbon=0;%碳排放归零                   fuelconsumptionofcar=0;                   Tabu(i,length(visited)+1)=1; %返回了起点                      dangqianvehiclevisittime=0;                   end  end  %%访问了需求点     % %if (load_w>vehiclecapacity) || ((dangqianvehiclevisittime>windowtime(to_visit(Select(1))))&&(dangqianvehiclevisittime<earlytime(to_visit(Select(1)))))% if (load_w>vehiclecapacity) || (dangqianvehiclevisittime>windowtime(to_visit(Select(1))))% %                    disp('该车辆服务完毕的的行驶时间')% %                    vehicletime%                    j=j-1;%没有选择到需求点,因此循环计数器减少一次%                    load_w=0;%车辆装载量归零%                    vehicletime=0;%服务时间归零%                    carcarbon=0;%碳排放归零%                    fuelconsumptionofcar=0;%                    Tabu(i,length(visited)+1)=1; %返回了起点   %                    dangqianvehiclevisittime=0;% else                 % %                  Tabu(i,length(visited)+1)=to_visit(Select(1)); %访问的节点%                     totaltimeofvehicletravle(i)=totaltimeofvehicletravle(i)+vehicletime;%%蚂蚁i所有的车辆行驶时间% %                     disp('+++++++++车辆的行驶时间之和+++++++++++++')% %                     totaltimeofvehicletravle(i)%                     anttraveldistance(i)=anttraveldistance(i)+pathlength;%%蚂蚁i所有车辆的行驶距离%                     factantcarbon(i)=factantcarbon(i)+carcarbon;%%蚂蚁i所有车辆的实际产生的碳排放%                     factfuelconsumptionofcar(i)=factfuelconsumptionofcar(i)+fuelconsumptionofcar;%                     vehicletime=0;%服务时间归零%                     fuelconsumptionofcar=0;%                      carcarbon=0;% end      %      disp('实际车辆行驶的时间')%      vehicletime%      totaltimeofvehicletravle(i)     j=j+1;     visited=Tabu(i,:);%已经访问的需求点     visited=visited(visited>0);     to_visit=setdiff(1:n,visited);%比较2个数组内不同的值,得出还没有访问的需求点     x=[];%清空没有访问的需求点的信息    if visited(end)~=1          Tabu(i,1:(length(visited)+1))=[visited,1];    end    end %  disp('车辆实际行驶的总时间')%  totaltimeofvehicletravle(i)%   disp('车辆实际行驶的路线')%  Tabu(i,:) end  %%全部M只蚂蚁循环访问控制 factfuelconsumptionofcar;factantcarbon;totaltimeofvehicletravle;anttraveldistance;Tabu; %%计算m只蚂蚁的各自的耗油量、行驶时间、行驶距离带来的总费用vehiclenumofeachant=zeros(1,m);%各只蚂蚁的总费用车辆数量anttotalcost=zeros(1,m);%各只蚂蚁的总费用初始化for i=1:m   nn=Tabu(i,:);   for j=2:length(nn)     if nn(j)==1        vehiclenumofeachant(i)=vehiclenumofeachant(i)+1;      end   end   anttotalcost(i)=anttraveldistance(i)*varityfeeofvehicle+vehiclenumofeachant(i)*fixfeeofvehicle+totaltimeofvehicletravle(i)*renlifeeunit+factfuelconsumptionofcar(i)*qiyoujiage+factantcarbon(i)*unitcarbonfee;%endbestcost=min(anttotalcost);%%找出总费用最优的路线weizhi=find(bestcost==anttotalcost); %%找出总费用最优的路线的位置kk=Tabu(weizhi,:);for x=1:length(kk)iterbestroute(x)=kk(x);end %%每次最好的计算结果记录if NC>=2  for x=1:length(kk)      Tabu(1,x)=iterbestroute(x);  end  enddangqianbestroute=iterbestroute(iterbestroute>0);%length_ave(NC)=mean(anttotalcost);%%以总费用作为目标的平均值length_ave(NC)=bestcost;%%以总费用作为目标的平均值 bijiaomubiao=bestcost;  %%本次程序的比较目标if NC==1    bestfuelconsumptionofcar=factfuelconsumptionofcar(weizhi);    bestroute=dangqianbestroute;    bestjuli=anttraveldistance(weizhi);    minmubiao=bijiaomubiao;    besttravletime=totaltimeofvehicletravle(weizhi);    bestcarbon=factantcarbon(weizhi);    else if bijiaomubiao<minmubiao    bestfuelconsumptionofcar=factfuelconsumptionofcar(weizhi);    bestroute=dangqianbestroute;    bestjuli=anttraveldistance(weizhi);       minmubiao=bijiaomubiao;    besttravletime=totaltimeofvehicletravle(weizhi);    bestcarbon=factantcarbon(weizhi);            endend     %% 第四步记录本代各种参数L=zeros(m,1);for i=1:m      MM=Tabu(i,:);      R=MM(MM>0);  for j=1:(length(R)-1)       L(i)=L(i)+D(R(j),R(j+1));   end end NC=NC+1 %迭代计数器%% 全局信息素更新%Delta_Tau=zeros(n,n); for i=1:m      MM=Tabu(i,:);      R=MM(MM>0);     cd=length(R);     for j=1:cd     Tabu(i,j)=R(j);     end  for j=1:(cd-1)     %Delta_Tau(R(j),R(j+1))=Delta_Tau(R(j),R(j+1))+Q/L(i);     Delta_Tau(Tabu(i,j),Tabu(i,j+1))=Delta_Tau(Tabu(i,j),Tabu(i,j+1))+Q/L(i); %此次循环在路径(i,j)上的信息素增量    end            %此次循环在整个路径上的信息素增量  end  Tau=(1-Rho).*Tau+Delta_Tau; %考虑信息素挥发,更新后的信息素   %% ????????? Tabu=zeros(m,n); load_w=0;end %%输出最优路线的相关信息    minmubiao    bestfuelconsumptionofcar    bestroute    bestjuli    besttravletime    bestcarbon     %% 画图画出路线subplot(1,2,1) plot([C(bestroute,1)],[C(bestroute,2)],'-*')%最优路径 subplot(1,2,2)                  %绘制第二个子图形% plot(iterbestlength)%各代的最短距离% hold onplot(length_ave,'r')%各代的平均距离% title('平均距离和最短距离')     %标题tocend

【VRP问题】基于蚁群算法求解带时间窗车辆调度问题_路径规划_08