天天看點

【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】

一、簡介

1 遺傳算法概述

遺傳算法(Genetic Algorithm,GA)是進化計算的一部分,是模拟達爾文的遺傳選擇和自然淘汰的生物進化過程的計算模型,是一種通過模拟自然進化過程搜尋最優解的方法。該算法簡單、通用,魯棒性強,适于并行處理。

2 遺傳算法的特點和應用

遺傳算法是一類可用于複雜系統優化的具有魯棒性的搜尋算法,與傳統的優化算法相比,具有以下特點:

(1)以決策變量的編碼作為運算對象。傳統的優化算法往往直接利用決策變量的實際值本身來進行優化計算,但遺傳算法是使用決策變量的某種形式的編碼作為運算對象。這種對決策變量的編碼處理方式,使得我們在優化計算中可借鑒生物學中染色體和基因等概念,可以模仿自然界中生物的遺傳和進化激勵,也可以很友善地應用遺傳操作算子。

(2)直接以适應度作為搜尋資訊。傳統的優化算法不僅需要利用目标函數值,而且搜尋過程往往受目标函數的連續性限制,有可能還需要滿足“目标函數的導數必須存在”的要求以确定搜尋方向。遺傳算法僅使用由目标函數值變換來的适應度函數值就可确定進一步的搜尋範圍,無需目标函數的導數值等其他輔助資訊。直接利用目标函數值或個體适應度值也可以将搜尋範圍集中到适應度較高部分的搜尋空間中,進而提高搜尋效率。

(3)使用多個點的搜尋資訊,具有隐含并行性。傳統的優化算法往往是從解空間的一個初始點開始最優解的疊代搜尋過程。單個點所提供的搜尋資訊不多,是以搜尋效率不高,還有可能陷入局部最優解而停滞;遺傳算法從由很多個體組成的初始種群開始最優解的搜尋過程,而不是從單個個體開始搜尋。對初始群體進行的、選擇、交叉、變異等運算,産生出新一代群體,其中包括了許多群體資訊。這些資訊可以避免搜尋一些不必要的點,進而避免陷入局部最優,逐漸逼近全局最優解。

(4) 使用機率搜尋而非确定性規則。傳統的優化算法往往使用确定性的搜尋方法,一個搜尋點到另一個搜尋點的轉移有确定的轉移方向和轉移關系,這種确定性可能使得搜尋達不到最優店,限制了算法的應用範圍。遺傳算法是一種自适應搜尋技術,其選擇、交叉、變異等運算都是以一種機率方式進行的,增加了搜尋過程的靈活性,而且能以較大機率收斂于最優解,具有較好的全局優化求解能力。但,交叉機率、變異機率等參數也會影響算法的搜尋結果和搜尋效率,是以如何選擇遺傳算法的參數在其應用中是一個比較重要的問題。

綜上,由于遺傳算法的整體搜尋政策和優化搜尋方式在計算時不依賴于梯度資訊或其他輔助知識,隻需要求解影響搜尋方向的目标函數和相應的适應度函數,是以遺傳算法提供了一種求解複雜系統問題的通用架構。它不依賴于問題的具體領域,對問題的種類有很強的魯棒性,是以廣泛應用于各種領域,包括:函數優化、組合優化生産排程問題、自動控制

、機器人學、圖像處理(圖像恢複、圖像邊緣特征提取…)、人工生命、遺傳程式設計、機器學習。

3 遺傳算法的基本流程及實作技術

基本遺傳算法(Simple Genetic Algorithms,SGA)隻使用選擇算子、交叉算子和變異算子這三種遺傳算子,進化過程簡單,是其他遺傳算法的基礎。

3.1 遺傳算法的基本流程

通過随機方式産生若幹由确定長度(長度與待求解問題的精度有關)編碼的初始群體;

通過适應度函數對每個個體進行評價,選擇适應度值高的個體參與遺傳操作,适應度低的個體被淘汰;

經遺傳操作(複制、交叉、變異)的個體集合形成新一代種群,直到滿足停止準則(進化代數GEN>=?);

将後代中變現最好的個體作為遺傳算法的執行結果。

【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】

其中,GEN是目前代數;M是種群規模,i代表種群數量。

3.2 遺傳算法的實作技術

基本遺傳算法(SGA)由編碼、适應度函數、遺傳算子(選擇、交叉、變異)及運作參數組成。

3.2.1 編碼

(1)二進制編碼

二進制編碼的字元串長度與問題所求解的精度有關。需要保證所求解空間内的每一個個體都可以被編碼。

優點:編、解碼操作簡單,遺傳、交叉便于實作

缺點:長度大

(2)其他編碼方法

格雷碼、浮點數編碼、符号編碼、多參數編碼等

3.2.2 适應度函數

适應度函數要有效反映每一個染色體與問題的最優解染色體之間的差距。

3.2.3選擇算子

【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】

3.2.4 交叉算子

交叉運算是指對兩個互相配對的染色體按某種方式互相交換其部分基因,進而形成兩個新的個體;交叉運算是遺傳算法差別于其他進化算法的重要特征,是産生新個體的主要方法。在交叉之前需要将群體中的個體進行配對,一般采取随機配對原則。

常用的交叉方式:

單點交叉

雙點交叉(多點交叉,交叉點數越多,個體的結構被破壞的可能性越大,一般不采用多點交叉的方式)

均勻交叉

算術交叉

3.2.5 變異算子

遺傳算法中的變異運算是指将個體染色體編碼串中的某些基因座上的基因值用該基因座的其他等位基因來替換,進而形成一個新的個體。

就遺傳算法運算過程中産生新個體的能力方面來說,交叉運算是産生新個體的主要方法,它決定了遺傳算法的全局搜尋能力;而變異運算隻是産生新個體的輔助方法,但也是必不可少的一個運算步驟,它決定了遺傳算法的局部搜尋能力。交叉算子與變異算子的共同配合完成了其對搜尋空間的全局搜尋和局部搜尋,進而使遺傳算法能以良好的搜尋性能完成最優化問題的尋優過程。

3.2.6 運作參數

【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】

4 遺傳算法的基本原理

4.1 模式定理

【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】

4.2 積木塊假設

具有低階、定義長度短,且适應度值高于群體平均适應度值的模式稱為基因塊或積木塊。

積木塊假設:個體的基因塊通過選擇、交叉、變異等遺傳算子的作用,能夠互相拼接在一起,形成适應度更高的個體編碼串。

積木塊假設說明了用遺傳算法求解各類問題的基本思想,即通過積木塊直接互相拼接在一起能夠産生更好的解。

二、源代碼

clc %清空指令行視窗
clear %從目前工作區中删除所有變量,并将它們從系統記憶體中釋放
close all %删除其句柄未隐藏的所有圖窗
tic % 儲存目前時間
%% GA-PSO算法求解DVRP
%輸入:
%City           需求點經緯度
%Distance       距離矩陣
%Travelcon      行程限制
%NIND           種群個數
%MAXGEN         遺傳到第MAXGEN代時程式停止

%輸出:
%Gbest          最短路徑
%GbestDistance	最短路徑長度

%% 加載資料
load('City.mat')	      %需求點經緯度,用于畫實際路徑的XY坐标
load('Distance.mat')	  %距離矩陣
load('Travelcon.mat')	  %行程限制

%% 初始化問題參數
CityNum=size(City,1)-1; %需求點個數

%% 初始化算法參數
NIND=60; %粒子數量
MAXGEN=100; %最大疊代次數

%% 為預配置設定記憶體而初始化的0矩陣
Population = zeros(NIND,CityNum*2+1); %預配置設定記憶體,用于存儲種群資料
PopDistance = zeros(NIND,1); %預配置設定矩陣記憶體
GbestDisByGen = zeros(MAXGEN,1); %預配置設定矩陣記憶體

for i = 1:NIND
    %% 初始化各粒子
    Population(i,:)=InitPop(CityNum,Distance,Travelcon); %随機生成TSP路徑
    
    %% 計算路徑長度
    PopDistance(i) = CalcDis(Population(i,:),Distance,Travelcon); % 計算路徑長度
end

%% 存儲Pbest資料
Pbest = Population; % 初始化Pbest為目前粒子集合
PbestDistance = PopDistance; % 初始化Pbest的目标函數值為目前粒子集合的目标函數值

%% 存儲Gbest資料
[mindis,index] = min(PbestDistance); %獲得Pbest中
Gbest = Pbest(index,:); % 初始Gbest粒子
GbestDistance = mindis; % 初始Gbest粒子的目标函數值

%% 開始疊代
gen=1;

while gen <= MAXGEN
    %% 每個粒子更新
    for i=1:NIND
        %% 粒子與Pbest交叉
        Population(i,2:end-1)=Crossover(Population(i,2:end-1),Pbest(i,2:end-1)); %交叉
        
        % 新路徑長度變短則記錄至Pbest
        PopDistance(i) = CalcDis(Population(i,:),Distance,Travelcon); %計算距離
        if PopDistance(i) < PbestDistance(i) %若新路徑長度變短
            Pbest(i,:)=Population(i,:); %更新Pbest
            PbestDistance(i)=PopDistance(i); %更新Pbest距離
        end
        
        %% 根據Pbest更新Gbest
        [mindis,index] = min(PbestDistance); %找出Pbest中最短距離

        if mindis < GbestDistance %若Pbest中最短距離小于Gbest距離
            Gbest = Pbest(index,:); %更新Gbest
            GbestDistance = mindis; %更新Gbest距離
        end
        
        %% 粒子與Gbest交叉
        Population(i,2:end-1)=Crossover(Population(i,2:end-1),Gbest(2:end-1));
        
        % 新路徑長度變短則記錄至Pbest
        PopDistance(i) = CalcDis(Population(i,:),Distance,Travelcon); %計算距離
        if PopDistance(i) < PbestDistance(i) %若新路徑長度變短
            Pbest(i,:)=Population(i,:); %更新Pbest
            PbestDistance(i)=PopDistance(i); %更新Pbest距離
        end
        function a=Crossover(a,b)
%% PMX方法交叉
%輸入:
%a  粒子代表的路徑
%b  個體最優粒子代表的路徑

%輸出:
%a	交叉後的粒子代表的路徑

L=length(a); %擷取親代染色體長度
r1=unidrnd(L); %在1~L中随機選一整數
r2=unidrnd(L); %在1~L中随機選一整數

s=min([r1,r2]); %起點為較小值
e=max([r1,r2]); %終點為較大值

b0=b(s:e); %用于最後插入

aa=a(s:e); %用于檢查重複元素
bb=b(s:e); %用于檢查重複元素

a(s:e)=[];     %去除交叉部分   去除後後面的元素會往前移

outlen=length(a); %去除交叉部分後,  a,b的長度   length outside cross section
inlen=e-s+1;      %交叉部分長度  length inside cross section 

for i=1:inlen     %交叉部分去除相同元素
	for j=1:inlen
		if aa(i)==bb(j) %若交叉部分内上下有相同元素
			aa(i)=0; %删去
			bb(j)=0;
			break  %  break能保證最後aa和bb一樣長 且無重複元素
		end
	end
end
function ttlDistance=CalcDis(route,Distance,Travelcon)
%% 計算各個體的路徑長度 适應度函數  
%輸入:
%route          某粒子代表的路徑
%Distance       兩兩城市之間的距離矩陣
%Travelcon     行程限制

%輸出:
%ttlDistance	種群個體路徑距離

%相關資料初始化
DisTraveled=0;  % 汽車已經行駛的距離
Dis=0; %此方案所有車輛的總距離
           

三、運作結果

【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】
【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】
【DVRP】遺傳和粒子群算法求解帶距離的VRP問題【含Matlab源碼 1036期】

四、備注

版本:2014a

繼續閱讀