天天看點

布谷鳥算法詳細講解

今天我要講的内容是布谷鳥算法,英文叫做Cuckoo search (CS algorithm)。首先還是同樣,介紹一下這個算法的英文含義, Cuckoo是布谷鳥的意思,啥是布谷鳥呢,是一種叫做布谷的鳥,o(∩_∩)o ,這種鳥她媽很懶,自己生蛋自己不養,一般把它的寶寶扔到别的種類鳥的鳥巢去。但是呢,當孵化後,遇到聰明的鳥媽媽,一看就知道不是親生的,直接就被鳥媽媽給殺了。于是這群布谷鳥寶寶為了保命,它們就模仿别的種類的鳥叫,讓智商或者情商極低的鳥媽媽誤認為是自己的親寶寶,這樣它就活下來了。 Search指的是搜尋,這搜尋可不是谷歌一下,你就知道。而是搜尋最優值,舉個簡單的例子,y=(x-0.5)^2+1,它的最小值是1,位置是(0.5,1),我們要搜尋的就是這個位置。

現在我們應該清楚它是幹嘛的了吧,它就是為了尋找最小值而産生的一種算法,有些好裝X的人會說,你傻X啊,最小值不是-2a/b嗎,用你找啊? 說的不錯,确實是,但是要是我們的函數變成 y=sin(x^3+x^2)+e^cos(x^3)+log(tan(x)+10,你怎麼辦吶?你解不了,就算你求導數,但是你知道怎麼解導數等于0嗎?是以我們就得引入先進的東西來求最小值。

為了使大家容易了解,我還是用y=(x-0.5)^2+1來舉例子,例如我們有4個布谷鳥蛋(也就是4個x坐标),鳥媽媽發現不是自己的寶寶的機率是0.25,我們x的取值範圍是[0,1]之間,于是我們就可以開始計算了。

目标:求x在[0,1]之内的函數y=(x-0.5)^2+1最小值

(1)初始化x的位置,随機生成4個x坐标,x1=0.4,x2=0.6,x3=0.8,x4=0.3 ——> X=[0.4, 0.6 ,0.8, 0.3]

(2)求出y1~y4,把x1~x4帶入函數,求得Y=[1,31, 1.46, 1.69, 1.265],并選取目前最小值ymin= y4=1.265

(3)開始定出一個y的最大值為Y_global=INF(無窮大),然後與ymin比較,把Y中最小的位置和值保留,例如Y_global=INF>ymin=1.265,是以令Y_global=1.265

(4)記錄Y_global的位置,(0.3,1.265)。

(5)按機率0.25,随機地把X中的值過塞子,選出被發現的蛋。例如第二個蛋被發現x2=0.6,那麼他就要随機地變換位子,生成一個随機數,例如0.02,然後把x2=x2+0.02=0.62,之後求出y2=1.4794。那麼X就變為了X=[0.4, 0.62 ,0.8, 0.3],Y=[1,31, 1.4794, 1.69, 1.265]。

(6)進行萊維飛行,這名字聽起來挺高大上,說白了,就是把X的位置給随機地改變了。怎麼變?有一個公式x=x+alpha*L。

L=S*(X-Y_global)*rand3

S=[rand1*sigma/|rand2|]^(1/beta)

sigma=0.6966

beta=1.5

alpha=0.01

rand1~rand3為正态分布的随機數

然後我們把X=[0.4, 0.6 ,0.8, 0.3]中的x1帶入公式,首先随機生成rand1=-1.2371,rand2=-2.1935,rand3=-0.3209,接下來帶入公式中,獲得x1=0.3985

之後同理計算:

x2=0.6172

x3=0.7889 

x4=0.3030

(7)更新矩陣X,X=[0.3985, 0.6172, 0.7889, 0.3030]

(8)計算Y=[1.3092, 1.4766, 1.6751, 1.2661],并選取目前最小值ymin= y4=1.2661,然後與ymin比較,把Y中最小的位置和值保留,例如Y_global=1.265<ymin=1.2661,是以令Y_global=1.265

(9)傳回步驟(5)用更新的X去循環執行,經過多次計算即可獲得y的最優值和的最值位置(x,y)

最後附上别人寫的代碼:

% -----------------------------------------------------------------
% Cuckoo Search (CS) algorithm by Xin-She Yang and Suash Deb      %
% Programmed by Xin-She Yang at Cambridge University              %
% Programming dates: Nov 2008 to June 2009                        %
% Last revised: Dec  2009   (simplified version for demo only)    %
% -----------------------------------------------------------------
% Papers -- Citation Details:
% 1) X.-S. Yang, S. Deb, Cuckoo search via Levy flights,
% in: Proc. of World Congress on Nature & Biologically Inspired
% Computing (NaBIC 2009), December 2009, India,
% IEEE Publications, USA,  pp. 210-214 (2009).
% http://arxiv.org/PS_cache/arxiv/pdf/1003/1003.1594v1.pdf 
% 2) X.-S. Yang, S. Deb, Engineering optimization by cuckoo search,
% Int. J. Mathematical Modelling and Numerical Optimisation, 
% Vol. 1, No. 4, 330-343 (2010). 
% http://arxiv.org/PS_cache/arxiv/pdf/1005/1005.2908v2.pdf
% ----------------------------------------------------------------%
% This demo program only implements a standard version of         %
% Cuckoo Search (CS), as the Levy flights and generation of       %
% new solutions may use slightly different methods.               %
% The pseudo code was given sequentially (select a cuckoo etc),   %
% but the implementation here uses Matlab's vector capability,    %
% which results in neater/better codes and shorter running time.  % 
% This implementation is different and more efficient than the    %
% the demo code provided in the book by 
%    "Yang X. S., Nature-Inspired Metaheuristic Algoirthms,       % 
%     2nd Edition, Luniver Press, (2010).                 "       %
% --------------------------------------------------------------- %

% =============================================================== %
% Notes:                                                          %
% Different implementations may lead to slightly different        %
% behavour and/or results, but there is nothing wrong with it,    %
% as this is the nature of random walks and all metaheuristics.   %
% -----------------------------------------------------------------

% Additional Note: This version uses a fixed number of generation %
% (not a given tolerance) because many readers asked me to add    %
%  or implement this option.                               Thanks.%                          
function [bestnest,fmin]=cuckoo_search_new(n)
if nargin<1,
% Number of nests (or different solutions)
n=25;
end

% Discovery rate of alien eggs/solutions
pa=0.25;

%% Change this if you want to get better results
N_IterTotal=1000;
%% Simple bounds of the search domain
% Lower bounds
nd=15; 
Lb=-5*ones(1,nd); 
% Upper bounds
Ub=5*ones(1,nd);

% Random initial solutions
for i=1:n,
nest(i,:)=Lb+(Ub-Lb).*rand(size(Lb));
end

% Get the current best
fitness=10^10*ones(n,1);
[fmin,bestnest,nest,fitness]=get_best_nest(nest,nest,fitness);

N_iter=0;
%% Starting iterations
for iter=1:N_IterTotal,
    % Generate new solutions (but keep the current best)
     new_nest=get_cuckoos(nest,bestnest,Lb,Ub);   
     [fnew,best,nest,fitness]=get_best_nest(nest,new_nest,fitness);
    % Update the counter
      N_iter=N_iter+n; 
    % Discovery and randomization
      new_nest=empty_nests(nest,Lb,Ub,pa) ;
    
    % Evaluate this set of solutions
      [fnew,best,nest,fitness]=get_best_nest(nest,new_nest,fitness);
    % Update the counter again
      N_iter=N_iter+n;
    % Find the best objective so far  
    if fnew<fmin,
        fmin=fnew;
        bestnest=best;
    end
end %% End of iterations

%% Post-optimization processing
%% Display all the nests
disp(strcat('Total number of iterations=',num2str(N_iter)));
fmin
bestnest

%% --------------- All subfunctions are list below ------------------
%% Get cuckoos by ramdom walk
function nest=get_cuckoos(nest,best,Lb,Ub)
% Levy flights
n=size(nest,1);
% Levy exponent and coefficient
% For details, see equation (2.21), Page 16 (chapter 2) of the book
% X. S. Yang, Nature-Inspired Metaheuristic Algorithms, 2nd Edition, Luniver Press, (2010).
beta=3/2;
sigma=(gamma(1+beta)*sin(pi*beta/2)/(gamma((1+beta)/2)*beta*2^((beta-1)/2)))^(1/beta);

for j=1:n,
    s=nest(j,:);
    % This is a simple way of implementing Levy flights
    % For standard random walks, use step=1;
    %% Levy flights by Mantegna's algorithm
    u=randn(size(s))*sigma;
    v=randn(size(s));
    step=u./abs(v).^(1/beta);
  
    % In the next equation, the difference factor (s-best) means that 
    % when the solution is the best solution, it remains unchanged.     
    stepsize=0.01*step.*(s-best);
    % Here the factor 0.01 comes from the fact that L/100 should the typical
    % step size of walks/flights where L is the typical lenghtscale; 
    % otherwise, Levy flights may become too aggresive/efficient, 
    % which makes new solutions (even) jump out side of the design domain 
    % (and thus wasting evaluations).
    % Now the actual random walks or flights
    s=s+stepsize.*randn(size(s));
   % Apply simple bounds/limits
   nest(j,:)=simplebounds(s,Lb,Ub);
end

%% Find the current best nest
function [fmin,best,nest,fitness]=get_best_nest(nest,newnest,fitness)
% Evaluating all new solutions
for j=1:size(nest,1),
    fnew=fobj(newnest(j,:));
    if fnew<=fitness(j),
       fitness(j)=fnew;
       nest(j,:)=newnest(j,:);
    end
end
% Find the current best
[fmin,K]=min(fitness) ;
best=nest(K,:);

%% Replace some nests by constructing new solutions/nests
function new_nest=empty_nests(nest,Lb,Ub,pa)
% A fraction of worse nests are discovered with a probability pa
n=size(nest,1);
% Discovered or not -- a status vector
K=rand(size(nest))>pa;

% In the real world, if a cuckoo's egg is very similar to a host's eggs, then 
% this cuckoo's egg is less likely to be discovered, thus the fitness should 
% be related to the difference in solutions.  Therefore, it is a good idea 
% to do a random walk in a biased way with some random step sizes.  
%% New solution by biased/selective random walks
stepsize=rand*(nest(randperm(n),:)-nest(randperm(n),:));
new_nest=nest+stepsize.*K;
for j=1:size(new_nest,1)
    s=new_nest(j,:);
  new_nest(j,:)=simplebounds(s,Lb,Ub);  
end

% Application of simple constraints
function s=simplebounds(s,Lb,Ub)
  % Apply the lower bound
  ns_tmp=s;
  I=ns_tmp<Lb;
  ns_tmp(I)=Lb(I);
  
  % Apply the upper bounds 
  J=ns_tmp>Ub;
  ns_tmp(J)=Ub(J);
  % Update this new move 
  s=ns_tmp;

%% You can replace the following by your own functions
% A d-dimensional objective function
function z=fobj(u)
%% d-dimensional sphere function sum_j=1^d (u_j-1)^2. 
%  with a minimum at (1,1, ...., 1); 
z=sum((u-1).^2);
           

繼續閱讀