1. 程式人生 > 其它 >m基於ACO蟻群演算法的考慮裝載率的迴圈送貨的最短線路規劃MATLAB模擬

m基於ACO蟻群演算法的考慮裝載率的迴圈送貨的最短線路規劃MATLAB模擬

1.演算法概述

        根據這些裝載率再結合路徑最短來設計幾個迴圈送貨的線路。最理想狀態是一條迴圈路徑出去把所有的貨都能遍歷,並且裝載率也很高。但是顯然理想狀態不可能,所以我們要做的就是儘量往理想狀態靠,通過這些資料,用最少的迴圈路徑條數(或者說最經濟的)和最高的裝載率以及最少的每條路徑遍歷次數(這些加起來基本就能看做是最低成本),來把那些貨運完。

根據你所提供的引數資料,目前,我們所需要考慮的影響成本的幾個因素為:

·每輛卡車的裝貨量;

·每個地點的座標值;

·每個地點的頻數,貨物種類以及數量,體積;

·卡車的耗油量;

    這裡由於原先考慮出現點問題,這裡考慮每輛卡車的優化方案分別進行模擬分析。

這裡所設計的環路方案,必須滿足如下的幾個條件:

第一:每個點通過次數必須滿足規定的頻次;

第二:從原點出發,在裝載率最大化的情況下儘可能多的歷遍點,然後返回節點;

第三:在完成所有節點的頻次需求和貨物需求所需要的路線最短即油耗最小。

        通過上面的分析,整個問題即,卡車每次裝多少種類的多少數目的貨物出發送貨(裝載量),且完成送貨任務總路徑最短,中間可能回來取貨(油耗),每個點通過次數在規定次數之內,此時的成本最低。並且,每次送貨的裝載量又決定了最終的路線長度即油耗,這裡省略掉時間成本。這裡單獨考慮每輛卡車的優化任務。

       通過上面的分析可知,這裡的優化問題,本質上是一個

VRPVFP的聯合問題,即車輛排程迴圈傳送和裝載的聯合問題。

這裡,我們的優化目標函式為:

 

這裡的函式含義是:

成本最低;

路徑綜合最短;

每條線路的裝載率最大;

2.模擬效果預覽

matlab2022a模擬結果如下:

 

3.核心MATLAB程式

.................................................................
 
%對映表
B = func_maps(C_f);
 
 
%計算規模和權值的初始值
[SCALEs,Wsd]=func_w(C); 
 
%中心和每個供貨點之間連線能節省的距離
Save_d = func_save_d(SCALEs,Wsd); 
 
LOADs                = 0;
Eer                  = 1./Wsd;                  %啟發常係數
Tau                  = ones(SCALEs,SCALEs); 
Save_roads           = zeros(Num_ann,SCALEs+20);%生成路的徑 
Iteration            = 1;                     
Best_roads           = [Iter,SCALEs+20];        %各代最佳路線 
Best_roads_Lens      = inf.*ones(Iter,1);       %各代最佳路線的長度 
Best_roads_Lens_avgs = zeros(Iter,1);           %各代路線的平均長度
flag                 = 0;
%進行蟻群+PSO演算法
while (Iteration <= Iter)
       disp('當前迭代次數')
       Iteration
       %產生隨機變數作為初始化粒子
       Save_roads(:,1) = randint(Num_ann,1,[1,1]);
       flag            = zeros(SCALEs,1);
       %按如下的規則進行迴圈歷遍
       pp              = 0;
       for i=1:Num_ann
            pp              = 0;
           %指定隨機性
%             RandStream.setDefaultStream(RandStream('mt19937ar','seed',Iteration*i));
           
            Will_walks   = Save_roads(i,:);
            Will_walks   = Will_walks(Will_walks>0);
            Will_walks2  = setdiff(1:SCALEs,Will_walks);
            c_temp       = length(Will_walks2);
            Jer=1;
            while Jer <= SCALEs
                  pp = pp +1;
                  if isempty(Will_walks2) == 0
                  %按照規則選下一個供貨點或者是回到中心
                     for k=1:length(Will_walks2)
                         x(k) = (Tau(Will_walks(end),Will_walks2(k))) *...
                                (Eer(Will_walks(end),Will_walks2(k))) *...
                                (Save_d(Will_walks(end),Will_walks2(k))^2);
                     end   
                     Pers = rand(1,1);
                     if Pers < 0.1
                        choices = find(max(x));
                     else
                        x       = x/(sum(x)); 
                        xcum    = cumsum(x); 
                        choices = find(xcum>=rand(1,1));
                     end
                     %以下是對每個供貨點進行供貨的裝載情況的計算
                     if isempty(choices) == 1
                        choices = 1;
                        %計算當前供貨點的物件數量和體積
                        INDs  = choices;
                        INDs2 = INDs;
                        LOADs = LOADs + V1{INDs2}(choices);
                     else
                        INDs  = Will_walks2(choices(1)); 
                        %對當前點下的情況進行裝貨
                        INDs2 = B(INDs,2);
                        %計算當前點種的貨物的種類
                        ZL    = length(V1{INDs2});
                        %%產生一組概率進行選擇貨物,如果裝載滿足需求,則繼續裝,否則不裝
                        %NNS   = floor(ZL*rand(1,1)) + 1; 
                        NNS = 1;
                        for NNS = 1:ZL
                            CC    = Nums{INDs2}(NNS);
                            while  CC > 0 & LOADs <= lemda*Qv
                               Vtmp  = V1{INDs2}(NNS);%選擇的貨物的體積大小
                               %然後進行裝載 
                               LOADs = LOADs + Vtmp;
                               %存貨數量減1
                               CC = CC-1;
                               Nums{INDs2}(NNS) = CC;
                            end
                        end
                     end
                     %計算裝載率
                     if LOADs <= lemda*Qv
                        WW(i,pp) = LOADs/(lemda*Qv);
                     end
 
                     if LOADs > lemda*Qv%裝滿則返回
                        choices                            = 1;
                        Jer                                = Jer-1;
                        LOADs                              = 0;
                        Save_roads(i,length(Will_walks)+1) = choices(1);
                     else
                        Save_roads(i,length(Will_walks)+1) = Will_walks2(choices(1)); 
                     end
                  end
                  Will_walks  = Save_roads(i,:);
                  Will_walks  = Will_walks(Will_walks>0);
                  Will_walks2 = setdiff(1:SCALEs,Will_walks);
                  x           = [];
                  if Will_walks(end) > 1 | Will_walks(end) < 1
                     Save_roads(i,1:(length(Will_walks)+1))=[Will_walks,1];
                  end
                 if sum(Nums{INDs2}) == 0
                    flag(Jer) = INDs;
                 else
                    flag(Jer) = 0; 
                 end                   
                 Jer=Jer+1;
                 
                  
            end
            LOADs=0;
       end
 
       L = zeros(Num_ann,1); 
       for i=1:Num_ann 
           tmpsss = Save_roads(i,:); 
           R      = tmpsss(tmpsss>0);
           for j=1:(length(R)-1)
               L(i) = L(i) + Wsd(R(j),R(j+1)); 
           end 
       end 
     
       Best_roads_Lens(Iteration)                           = min(L); 
       pos                                                  = find(L==Best_roads_Lens(Iteration)); 
       Best_roads(Iteration,1:length(Save_roads(pos(1),:))) = Save_roads(pos(1),:);
       SELS                                                 = find(Best_roads(Iteration,:)==1);
       Best_save                                            = [];
       Best_save2                                           = 0;
       for Si=1:(length(SELS)-1)
           YBEST = Best_roads(Iteration,SELS(Si):SELS(Si+1));
           al    = length(YBEST);
           T     = zeros((length(SELS)-1),1);
           for Sj=1:(al-1)
               T(Si)=T(Si)+Wsd(YBEST(Sj),YBEST(Sj+1));
           end
           for Sp=2:(al-1)
               for Sq=(Sp+1):(al-1)
                   DD     = YBEST;
                   temp1  = DD(Sp);
                   temp2  = DD(Sq);
                   DD(Sp) = temp2;
                   DD(Sq) = temp1;
                   TT     = zeros(1);
                   for Sj=1:(al-1)
                       TT = TT + Wsd(DD(Sj),DD(Sj+1));
                   end
                   if TT<T(Si)
                      T(Si) = TT;
                      YBEST = DD;
                   end
               end
           end
           if Si>=2
               YBEST = YBEST(2:al);
           end
           Best_save = [Best_save,YBEST];
           Best_save2= Best_save2+T(Si);
       end
       Best_roads_Lens(Iteration)                = Best_save2;
       Best_roads(Iteration,1:length(Best_save)) = Best_save;
       
       Best_save                          = [];
       Best_save2                         = 0;
       Best_roads_Lens_avgs(Iteration)    = mean(L); 
       LOADs                              = 0;
       Iteration                          = Iteration+1;
       Delta_Tau=zeros(SCALEs,SCALEs); 
       for i=1:Num_ann 
           MM = Save_roads(i,:); 
           R  = MM(MM>0);
           for j=1:(length(R)-1) 
               Delta_Tau(R(j),R(j+1))=Delta_Tau(R(j),R(j+1))+Importance/L(i); 
           end 
       end 
       Tau        = (1-Rr).*Tau+Delta_Tau;
       %清零 
       Save_roads = zeros(Num_ann,SCALEs); 
       
end
 
%優化結果 
Pos        = find(Best_roads_Lens==min(Best_roads_Lens)); 
best_route = Best_roads(Pos(1),:);
best_route = best_route(best_route>0);
for i = 1:SCALEs
    Load_rate(i)  = mean(WW(:,i));
end
%裝載率的變化
%裝載率的變化
disp('裝載率:');
max(Load_rate)
 
.................................
02-008m