蟻群算法MATLAB解VRP問題


Excel  exp12_3_2.xls內容:

 

ANT_VRP函數:

function [R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ANT_VRP(D,Demand,Cap,iter_max,m,Alpha,Beta,Rho,Q)

%% R_best 各代最佳路線
%% L_best 各代最佳路線的長度
%% L_ave 各代平均距離
%% Shortest_Route 最短路徑
%% Shortest_Length 最短路徑長度
%% D 城市間之間的距離矩陣,為對稱矩陣
%% Demand 客戶需求量
%% Cap 車輛最大載重
%% iter_max 最大迭代次數
%% m 螞蟻個數
%% Alpha 表征信息素重要程度的參數
%% Beta 表征啟發式因子重要程度的參數
%% Rho 信息素蒸發系數
%% Q 信息素增加強度系數

n=size(D,1);                 
T=zeros(m,2*n);           %裝載距離
Eta=ones(m,2*n);          %啟發因子
Tau=ones(n,n);            %信息素
Tabu=zeros(m,n);          %禁忌表
Route=zeros(m,2*n);       %路徑
L=zeros(m,1);             %總路程
L_best=zeros(iter_max,1);   %各代最佳路線長度
R_best=zeros(iter_max,2*n); %各代最佳路線
nC=1;

while nC<=iter_max                   %停止條件
    Eta=zeros(m,2*n);   
    T=zeros(m,2*n);  
    Tabu=zeros(m,n);
    Route=zeros(m,2*n);
    L=zeros(m,1);
    
    %%%%%%==============初始化起點城市(禁忌表)====================
    for i=1:m
        Cap_1=Cap;      %最大裝載量
        j=1;
        j_r=1;
        while Tabu(i,n)==0
             T=zeros(m,2*n);    %裝載量加載矩陣
             Tabu(i,1)=1;       %禁忌表起點位置為1
             Route(i,1)=1;      %路徑起點位置為1
             visited=find(Tabu(i,:)>0);   %已訪問城市
             num_v=length(visited);        %已訪問城市個數
             J=zeros(1,(n-num_v));         %待訪問城市加載表
             P=J;                          %待訪問城市選擇概率分布
             Jc=1;                         %待訪問城市選擇指針
             for k=1:n                     %城市
                 if length(find(Tabu(i,:)==k))==0    %如果k不是已訪問城市代號,就將k加入矩陣J中
                     J(Jc)=k;
                     Jc=Jc+1;
                 end
             end
             
           %%%%%%%=============每只螞蟻按照選擇概率遍歷所有城市==================
             
             for k=1:n-num_v               %待訪問城市
                 
                   if Cap_1-Demand(J(1,k),1)>=0    %如果車輛裝載量大於待訪問城市需求量

                     if Route(i,j_r)==1           %如果每只螞蟻在起點城市
                         T(i,k)=D(1,J(1,k));
                         P(k)=(Tau(1,J(1,k))^Alpha)*((1/T(i,k))^Beta);  %概率計算公式中的分子
                     else                         %如果每只螞蟻在不在起點城市
                         T(i,k)=D(Tabu(i,j),J(1,k));
                         P(k)=(Tau(Tabu(i,visited(end)),J(1,k))^Alpha)*((1/T(i,k))^Beta); %概率計算公式中的分子
                     end
                     
                 else              %如果車輛裝載量小於待訪問城市需求量
                     T(i,k)=0;
                     P(k)=0;
                 end
             end
             
             
             if length(find(T(i,:)>0))==0    %%%當車輛裝載量小於待訪問城市時,選擇起點為1
                 Cap_1=Cap;
                 j_r=j_r+1;
                 Route(i,j_r)=1;              
                 L(i)=L(i)+D(1,Tabu(i,visited(end)));   
             else
                 P=P/(sum(P));                 %按照概率原則選取下一個城市
                 Pcum=cumsum(P);               %求累積概率和:cumsum([1 2 3])=1 3 6,目的在於使得Pcum的值總有大於rand的數
                 Select=find(Pcum>rand);       %按概率選取下一個城市:當累積概率和大於給定的隨機數,則選擇求和被加上的最后一個城市作為即將訪問的城市
                 o_visit=J(1,Select(1));       %待訪問城市
                 j=j+1;
                 j_r=j_r+1;
                 Tabu(i,j)=o_visit;             %待訪問城市
                 Route(i,j_r)=o_visit;
                 Cap_1=Cap_1-Demand(o_visit,1);  %車輛裝載剩余量
                 L(i)=L(i)+T(i,Select(1));       %路徑長度
             end
        end
         L(i)=L(i)+D(Tabu(i,n),1);               %%路徑長度
    end
    
    L_best(nC)=min(L);             %最優路徑為距離最短的路徑
    pos=find(L==min(L));           %找出最優路徑對應的位置:即為哪只螞蟻
    R_best(nC,:)=Route(pos(1),:);  %確定最優路徑對應的城市順序
    L_ave(nC)=mean(L)';            %求第k次迭代的平均距離
    
    Delta_Tau=zeros(n,n);            %Delta_Tau(i,j)表示所有螞蟻留在第i個城市到第j個城市路徑上的信息素增量
    L_zan=L_best(1:nC,1);
    post=find(L_zan==min(L_zan));
    Cities=find(R_best(nC,:)>0);
    num_R=length(Cities);
    
    for k=1:num_R-1          %建立了完整路徑后在釋放信息素
        Delta_Tau(R_best(nC,k),R_best(nC,k+1))=Delta_Tau(R_best(nC,k),R_best(nC,k+1))+Q/L_best(nC);
    end
        Delta_Tau(R_best(nC,num_R),1)=Delta_Tau(R_best(nC,num_R),1)+Q/L_best(nC);
        Tau=Rho*Tau+Delta_Tau;
        
        nC=nC+1;
end
Shortest_Route=zeros(1,2*n);           %提取最短路徑
Shortest_Route(1,:)=R_best(iter_max,:);
Shortest_Route=Shortest_Route(Shortest_Route>0);
Shortest_Route=[Shortest_Route Shortest_Route(1,1)];
Shortest_Length=min(L_best);           %提取最短路徑長度
%L_ave=mean(L_best);

  求解程序:

clc;clear all
%% ==============提取數據==============
[xdata,textdata]=xlsread('exp12_3_2.xls'); %加載20個城市的數據,數據按照表格中位置保存在Excel文件exp12_3_1.xls中
x_label=xdata(:,2); %第二列為橫坐標
y_label=xdata(:,3); %第三列為縱坐標
Demand=xdata(:,4);  %第四列為需求量
C=[x_label y_label];      %坐標矩陣
n=size(C,1);        %n表示節點(客戶)個數
%% ==============計算距離矩陣==============
D=zeros(n,n);       %D表示完全圖的賦權鄰接矩陣,即距離矩陣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)=0;   %i=j, 則距離為0;
       end
       D(j,i)=D(i,j);  %距離矩陣為對稱矩陣
   end
end
Alpha=1;Beta=5;Rho=0.75;iter_max=100;Q=10;Cap=1;m=20;  %Cap為車輛最大載重
[R_best,L_best,L_ave,Shortest_Route,Shortest_Length]=ANT_VRP(D,Demand,Cap,iter_max,m,Alpha,Beta,Rho,Q); %蟻群算法求解VRP問題通用函數,詳見配套光盤
Shortest_Route_1=Shortest_Route-1    %提取最優路線
Shortest_Length                      %提取最短路徑長度

%% ==============作圖==============
figure(1)   %作迭代收斂曲線圖
x=linspace(0,iter_max,iter_max);
y=L_best(:,1);
plot(x,y);
xlabel('迭代次數'); ylabel('最短路徑長度');

figure(2)   %作最短路徑圖
plot([C(Shortest_Route,1)],[C(Shortest_Route,2)],'o-');
grid on
for i =1:size(C,1)
    text(C(i,1),C(i,2),['   ' num2str(i-1)]); 
end
xlabel('客戶所在橫坐標'); ylabel('客戶所在縱坐標');

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM