[转载]布谷鸟算法的程序(个人注释)
生活随笔
收集整理的這篇文章主要介紹了
[转载]布谷鸟算法的程序(个人注释)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近項目需要,所以一直在研究布谷鳥算法,在網上看了一些前輩的文章,原理講的都比較透徹,我就不再贅述。貼上一個自己注釋的程序吧(這個程序也是借鑒別的大佬的,小小的做了一些修改)我也是最近才接觸布谷鳥算法,肯定有欠妥之處,希望各位大佬多多批評指正,相互學習
function [bestnest,fmin]=cuckoo_search(n)
if nargin<1,%【如果變量的個數小于1】
% Number of nests (or different solutions)
n=15;%【則把種群數量設為15,種群數量越多,最后算法的求解越精確,但程序的運行時間也會大大拉長】
end% Discovery rate of alien eggs/solutions
pa=0.25;%【布谷鳥蛋被發現的概率】%% Change this if you want to get better results
% Tolerance
Tol=1.0e-5; %閾值【循環的精度設置】%% Simple bounds of the search domain
nd=6; %【需要尋優的參數個數,即搜索空間維度為nd】
% Lower bounds【鳥窩范圍的下限】
Lb=-100*ones(1,nd);
% Upper bounds【鳥窩范圍的上限】
Ub=100*ones(1,nd);% Random initial solutions【把鳥窩的初始值設為隨機值,即初始化所有鳥窩的位置】
nest=zeros(n,nd); %【nest為n行nd列的零矩陣,先把最初的鳥巢設為零矩陣】
for i=1:n,%【這是個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 kk = 1 : 500%可以通過for循環代替下面的while
while (fmin>Tol),%【只要沒達到這個精度,循環就會一直進行】% 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; %【因為每次都要遍歷所有巢穴,所以在這里每次迭代都要+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;%【則用新的鳥窩的值替換原fmin中的數據】bestnest=best;%【并且把此鳥窩下的各個參數的最優解賦給bestnest】enddisp(strcat('Total number of iterations=【當前已進行的迭代尋優次數】',num2str(N_iter)));
fmin
bestnest
end %% End of iterations【結束布谷鳥尋優進程】%% Post-optimization processing
%% Display all the nests【循環內外各寫一遍就是為了看它不斷迭代的過程以及最終結果】
disp(strcat('Total number of iterations=【迭代尋優的總次數】',num2str(N_iter)));
fmin
bestnest
figure; %【出現最終n個曲線的圖(n就是鳥窩個數)】
plot(nest);
xlabel '鳥巢的個數' %【x軸的名稱】
ylabel '待定參數的估計值' %【y軸的名稱】%% --------------- All subfunctions are list below ------------------
%% Get cuckoos by ramdom walk【用隨機游走來加強布谷鳥算法】【萊維飛行】
function nest=get_cuckoos(nest,best,Lb,Ub)
% Levy flights【萊維飛行,是個固定程式,固定的給出隨機數的公式模型,無須修改,了解即可】
%【當然,如果要進行算法改進可以在這里做文章,比如用柯西來替代萊維飛行,就是基于柯西原理的改進的布谷鳥算法】
%【萊維飛行本質上是一個基于馬爾科夫鏈(下一狀態取決于當前狀態)的隨機行走公式】
%【萊維飛行可以使布谷鳥尋優綜合局部尋優和全局尋優】
n=size(nest,1);%【n是一個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);%【sigma這個數約等于0.7】
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%【randn函數是產生均值為0,方差σ^2 = 1,標準差σ = 1的正態分布的隨機數或矩陣的函數。】u=randn(size(s))*sigma;%【產生一個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 flightss=s+stepsize.*randn(size(s));%【s又變了個數】% Apply simple bounds/limitsnest(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),%【j從1循環到nest的行數】fnew=fobj(newnest(j,:));%【在目標函數中進行運算 ,并把z的值賦值給fnew】if fnew<=fitness(j),%【這個if語句用來判斷是否滿足精度,若更好則替換】fitness(j)=fnew;nest(j,:)=newnest(j,:);end
end
% Find the current best
[fmin,K]=min(fitness) ;%【fmin記錄列向量fitness的每列的最小值,K記錄每列最小值的行號】
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【劣質巢穴會以pa的概率被淘汰】
n=size(nest,1);
% Discovered or not -- a status vector【發現與否——狀態向量】
K=rand(size(nest))>pa;%【如果產生的隨機數大于pa的值,就令K等于該值】
% 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),:));
%randperm會將數字順序隨機打亂,將1~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的值小于Lb,則把臨時變量ns_tmp中存儲的s的值賦給I】ns_tmp(I)=Lb(I);% Apply the upper bounds J=ns_tmp>Ub;ns_tmp(J)=Ub(J);% Update this new move 【把s這個值更新】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-4).^2);
總結
以上是生活随笔為你收集整理的[转载]布谷鸟算法的程序(个人注释)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10 android10之后高通芯
- 下一篇: 从游击队到正规军(三):基于Go的马蜂窝