差分進化演算法介紹及matlab實現

爭不過朝夕發表於2020-11-19

引言


差分進化演算法是基於群體智慧理論的優化演算法,是通過群體內個體間的合作與競爭而產生的智慧優化搜尋演算法,它保留了基於種群的全域性搜尋策略,採用實數編碼、基於差分的簡單變異操作和“一對一”的競爭生存策略,降低了進化計算操作的複雜性。

差分進化演算法的原理


差分進化演算法是一種自組織最小化方法,利用種群中兩個隨機選擇的不同向量來干擾現有向量,種群中的每一個向量都要進行干擾。

  1. 它通過把種群中的兩個成員之間的加權差向量加到第三個成員上來產生新的引數向量,該操作成為“變異”。
  2. 將變異向量的引數與另外預先確定的目標向量引數按一定規則混合來產生實驗向量,該操作成為“交叉”;
  3. 若實驗向量的代價函式比目標向量的代價函式低,實驗向量就在下一代中替代目標向量,該操作成為“選擇”;

差分進化演算法流程


具體步驟如下:

  1. 確定差分進化演算法的控制引數和所要採用的具體策略。控制引數包括:種群數量、變異運算元、交叉運算元、最大進化代數、終止條件等。
  2. 隨機產生初始種群,進化代數k=1;
  3. 對初始種群進行評價,即計算初始種群中每個個體的目標函式值。
  4. 判斷是否達到終止條件或達到最大進化代數;若是,則進化終止,將此時的最佳個體作為解輸出;否則,繼續下一步操作。
  5. 進行變異操作和交叉操作,對邊界條件進行處理,得到臨時種群。
  6. 對臨時種群進行評價,計算臨時種群中每個個體的目標函式值。
  7. 對臨時種群中的個體和原種群中對應的個體,進行“一對一”的選擇操作,得到新種群。
  8. 進化代數k=k+1,轉步驟(4).

例項:

 

 

$$計算函式的最小值,其中個體x的維數n=10.這是一個簡單的平方和函式,只有一個極小點x=(0,0,...,0)。$$

%%%%%%%差分進化求函式極值%%%%%%%%%
%%%%%%%初始化%%%%%%%%
clear all;
close all;
clc;
NP = 50;       %種群的數量
D = 10;        %變數的維度
G = 200;       %最大進化代數
F0 = 0.4;      %初始變異運算元
CR = 0.1;      %交叉運算元
Xs = 20;                            %上限
Xx = -20;                           %下限
yz = 10^-6;                         %閾值
%%%%%%%%賦初值%%%%%%%%%%%%
x = zeros(D,NP);                    %初始種群
v = zeros(D,NP);                    %變異種群
u = zeros(D,NP);                    %選擇種群
x = rand(D,NP) * (Xs-Xx) + Xx;      %賦初值
%%%%%%%%%%計算目標函式%%%%%%%%%%%
for m = 1:NP
   Ob(m) = func1(x(:,m)); 
end
trace(1) = min(Ob);
%%%%%%%%%差分進化迴圈%%%%%%%%%%
for gen = 1:G
   %%%%%%%%%%%變異操作%%%%%%%%%%%%%%%%%%%
   %%%%%%%%%%%自適應變異運算元%%%%%%%
   lamda = exp(1-G/(G+1-gen));
   F = F0*2^(lamda);
   %%%%%%%%r1,r2,r3和m互不相同%%%%
   for m = 1:NP
      r1 = randi([1,NP],1,1);
      while(r1 == m)
          r1 = randi([1,NP],1,1);
      end
      r2 = randi([1,NP],1,1);
      while (r2 == m) | (r2 == r1)
          r2 = randi([1,NP],1,1);
      end
      r3 = randi([1,NP],1,1);
      while (r3 == m) | (r3 == r1 | r3 == r2)
          r3 = randi([1,NP],1,1);
      end
      v(:,m) = x(:,r1) + F * (x(:,r2) - x(:,r3));
   end
   %%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%
   r = randi([1,NP],1,1);      %確保必有一個v(:)進入u(:)中
   for n = 1:D
      cr = rand(1);
      if (cr <= CR) | (n == r)
         u(n,:) = v(n,:);       %批量操作,替換所有個體第n維
      else
          u(n,:) = x(n,:);
      end
   end
   %%%%%%%%%%%%%%%%邊界條件的處理%%%%%%%%%%%%%%%
   for n = 1:D
      for m = 1:NP
         if (u(n,m) < Xx) | (u(n,m) > Xs)
            u(n,m) = rand * (Xs - Xx) + Xx; 
         end
      end
   end
   %%%%%%%%%%%%%%%%選擇操作%%%%%%%%%%%%%%%%%%%%
   for m = 1:NP
      Ob1(m) = func1(u(:,m)); 
   end
   for m = 1:NP
      if Ob1(m) < Ob(m)
         x(:,m) = u(:,m); 
      end
   end
   for m = 1:NP
      Ob(m) = func1(x(:,m)); 
   end
   trace(gen+1) = min(Ob);
   if min(Ob) < yz
      break; 
   end
end
%%%%%%%%%%%%%%%%畫圖%%%%%%%%%%%%%%%
figure
plot(trace);
xlabel('迭代次數');
ylabel('目標函式值');
title('DE目標函式曲線');
%%%%%%%%%%%%%%適應度函式%%%%%%%%%%
function result = func1(x)
summ = sum(x.^2);
result = summ;
end

  

相關文章