【蚁狮算法】《The Ant Lion Optimizer》matlab代码浅析

上一篇介绍了蚁狮算法的数学模型:

【蚁狮算法】《The Ant Lion Optimizer》原文翻译(附源代码)

蚁狮算法matlab源代码下载地址:

http://www.alimirjalili.com/SourceCodes/ALO.zip

地址2:下载地址

下载之后可以看到代码目录如下:

接下来将一一解析m文件

目录

main.m

参数:

代码:

Get_Functions_details.m

代码:

func_plot.m

代码:

initialization.m

代码:

ALO.m

代码:

RouletteWheelSelection.m

代码:

Random_walk_around_antlion.m

代码:


main.m

设置参数并显示优化结果

参数:

fobj:成本函数

dim:变量维度

Max_iteration:最大迭代次数

SearchAgents_no:蚁狮的数量

lb=[lb1,lb2,...,lbn]:lb 是n个变量中最小的数

ub=[ub1,ub2,...,ubn]:ub 是n个变量中最大的数

(参考各函数对应的取值范围,如果所有的变量都有相等的下限,你可以直接将 lb 和 ub 定义为同一个的数字)

Function_name:测试函数,可设为 F1~F23,函数的定义见 Get_Functions_details.m

代码:

% You can simply define your cost in a seperate file and load its handle to fobj 
% The initial parameters that you need are:
%__________________________________________
% fobj = @YourCostFunction
% dim = number of your variables
% Max_iteration = maximum number of generations
% SearchAgents_no = number of search agents
% lb=[lb1,lb2,...,lbn] where lb is the lower bound of variable n
% ub=[ub1,ub2,...,ubn] where ub is the upper bound of variable n
% If all the variables have equal lower bound you can just
% define lb and ub as two single number numbers

% To run ALO: [Best_score,Best_pos,cg_curve]=ALO(SearchAgents_no,Max_iteration,lb,ub,dim,fobj)
%__________________________________________

clear all 
clc

SearchAgents_no=40; % Number of search agents

Function_name='F1'; % Name of the test function that can be from F1 to F23 (Table 1,2,3 in the paper)

Max_iteration=500; % Maximum numbef of iterations

% Load details of the selected benchmark function
[lb,ub,dim,fobj]=Get_Functions_details(Function_name);

[Best_score,Best_pos,cg_curve]=ALO(SearchAgents_no,Max_iteration,lb,ub,dim,fobj);

figure('Position',[500 500 660 290])
%Draw search space
subplot(1,2,1);
func_plot(Function_name);
title('Test function')
xlabel('x_1');
ylabel('x_2');
zlabel([Function_name,'( x_1 , x_2 )'])
grid off

%Draw objective space
subplot(1,2,2);
semilogy(cg_curve,'Color','r')
title('Convergence curve')
xlabel('Iteration');
ylabel('Best score obtained so far');

axis tight
grid off
box on
legend('ALO')

display(['The best solution obtained by ALO is : ', num2str(Best_pos)]);
display(['The best optimal value of the objective funciton found by ALO is : ', num2str(Best_score)]);

Get_Functions_details.m

测试所用的函数。根据论文中函数的定义,利用 switch-case 结构编写代码。

单峰基准函数:

多峰基准函数:

复合基准函数:

代码:

function [lb,ub,dim,fobj] = Get_Functions_details(F)

switch F
    case 'F1'
        fobj = @F1;
        lb=-100;
        ub=100;
        dim=10;
        
    case 'F2'
        fobj = @F2;
        lb=-10;
        ub=10;
        dim=10;
        
    case 'F3'
        fobj = @F3;
        lb=-100;
        ub=100;
        dim=10;
        
    case 'F4'
        fobj = @F4;
        lb=-100;
        ub=100;
        dim=10;
        
    case 'F5'
        fobj = @F5;
        lb=-30;
        ub=30;
        dim=10;
...
% F1

function o = F1(x)
o=sum(x.^2);
end

% F2

function o = F2(x)
o=sum(abs(x))+prod(abs(x));
end

% F3

function o = F3(x)
dim=size(x,2);
o=0;
for i=1:dim
    o=o+sum(x(1:i))^2;
end
end
...

func_plot.m

绘制函数图像

代码:

% This function draws the benchmark functions

function func_plot(func_name)

[lb,ub,dim,fobj]=Get_Functions_details(func_name);

switch func_name 
    case 'F1' 
        x=-100:2:100; y=x; %[-100,100]
        
    case 'F2' 
        x=-100:2:100; y=x; %[-10,10]
        
    case 'F3' 
        x=-100:2:100; y=x; %[-100,100]
        
    case 'F4' 
        x=-100:2:100; y=x; %[-100,100]
    case 'F5' 
        x=-200:2:200; y=x; %[-5,5]
    case 'F6' 
        x=-100:2:100; y=x; %[-100,100]
    case 'F7' 
        x=-1:0.03:1;  y=x  %[-1,1]
    case 'F8' 
        x=-500:10:500;y=x; %[-500,500]
    case 'F9' 
        x=-5:0.1:5;   y=x; %[-5,5]    
    case 'F10' 
        x=-20:0.5:20; y=x;%[-500,500]
    case 'F11' 
        x=-500:10:500; y=x;%[-0.5,0.5]
    case 'F12' 
        x=-10:0.1:10; y=x;%[-pi,pi]
    case 'F13' 
        x=-5:0.08:5; y=x;%[-3,1]
    case 'F14' 
        x=-100:2:100; y=x;%[-100,100]
    case 'F15' 
        x=-5:0.1:5; y=x;%[-5,5]
    case 'F16' 
        x=-1:0.01:1; y=x;%[-5,5]
    case 'F17' 
        x=-5:0.1:5; y=x;%[-5,5]
    case 'F18' 
        x=-5:0.06:5; y=x;%[-5,5]
    case 'F19' 
        x=-5:0.1:5; y=x;%[-5,5]
    case 'F20' 
        x=-5:0.1:5; y=x;%[-5,5]        
    case 'F21' 
        x=-5:0.1:5; y=x;%[-5,5]
    case 'F22' 
        x=-5:0.1:5; y=x;%[-5,5]     
    case 'F23' 
        x=-5:0.1:5; y=x;%[-5,5]  
end    

    

L=length(x);
f=[];

for i=1:L
    for j=1:L
        if strcmp(func_name,'F15')==0 && strcmp(func_name,'F19')==0 && strcmp(func_name,'F20')==0 && strcmp(func_name,'F21')==0 && strcmp(func_name,'F22')==0 && strcmp(func_name,'F23')==0
            f(i,j)=fobj([x(i),y(j)]);
        end
        if strcmp(func_name,'F15')==1
            f(i,j)=fobj([x(i),y(j),0,0]);
        end
        if strcmp(func_name,'F19')==1
            f(i,j)=fobj([x(i),y(j),0]);
        end
        if strcmp(func_name,'F20')==1
            f(i,j)=fobj([x(i),y(j),0,0,0,0]);
        end       
        if strcmp(func_name,'F21')==1 || strcmp(func_name,'F22')==1 ||strcmp(func_name,'F23')==1
            f(i,j)=fobj([x(i),y(j),0,0]);
        end          
    end
end

surfc(x,y,f,'LineStyle','none');

end

initialization.m

产生第一代蚂蚁和蚁狮的随机位置

ub 和 lb 由 Get_Functions_details(Function_name) 给出

X=rand(SearchAgents_no,dim).*(ub-lb)+lb 和 X(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i 都是归一化操作

对照原文:

X_{i}^{t}=\frac{\left(X_{i}^{t}-a_{i}\right) \times\left(d_{i}^{t}-c_{i}^{t}\right)}{\left(d_{i}-a_{i}\right)}+c_{i}^{t}

  其中 a_i 是第 i 个变量的随机游走的最小值,d_i  是第 i 个变量中的随机游走的最大值,c_i^t 是在第 t 次迭代时第 i 个变量的最小值,d_i^t 表示第 t 次迭代的第 i 个变量的最大值。

代码:

function X=initialization(SearchAgents_no,dim,ub,lb)

Boundary_no= size(ub,2); % 边界数量

% 如果所有变量的边界相等
if Boundary_no==1
    X=rand(SearchAgents_no,dim).*(ub-lb)+lb;
end

% 如果不同变量的边界不同
if Boundary_no>1
    for i=1:dim
        ub_i=ub(i);
        lb_i=lb(i);
        X(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i;
    end
end

ALO.m

初始化蚁狮 antlion_position 和蚂蚁的位置 ant_position,初始化排序后蚁狮位置 Sorted_antlions 、精英蚁狮位置 Elite_antlion_position 、精英蚁狮适应度 Elite_antlion_fitness 、收敛曲线 Convergence_curve 、蚁狮适应度 antlions_fitness 、蚂蚁适应度 ants_fitness 。

% 初始化蚁狮和蚂蚁的位置
antlion_position=initialization(N,dim,ub,lb);
ant_position=initialization(N,dim,ub,lb);

% 初始化排序后蚁狮位置、精英蚁狮位置、精英蚁狮适应度、收敛曲线、蚁狮适应度、蚂蚁适应度
Sorted_antlions=zeros(N,dim);
Elite_antlion_position=zeros(1,dim);
Elite_antlion_fitness=inf;
Convergence_curve=zeros(1,Max_iter);
antlions_fitness=zeros(1,N);
ants_fitness=zeros(1,N);

根据损失函数 fobj (由Get_Functions_details.m给出)计算第一代的蚁狮适应度并用 sort 函数排序,将计算结果最小即适应度最大的蚁狮设为精英蚁狮。

for i=1:size(antlion_position,1)
    antlions_fitness(1,i)=fobj(antlion_position(i,:)); 
end

[sorted_antlion_fitness,sorted_indexes]=sort(antlions_fitness);
    
for newindex=1:N
     Sorted_antlions(newindex,:)=antlion_position(sorted_indexes(newindex),:);
end
    
Elite_antlion_position=Sorted_antlions(1,:);
Elite_antlion_fitness=sorted_antlion_fitness(1);

设 Max_iter = 500 , N = 40 , ub = 100 , lb = -100 , dim = 10 ,  fobj 选择 F1,运行后得到40个蚁狮适应度 antlions_fitness 如下:

12345678910
3.1682E+042.6423E+043.4530E+042.5782E+042.5871E+042.0789E+042.2776E+042.9961E+043.3678E+042.2502E+04
11121314151617181920
3.9170E+045.4611E+043.1453E+045.1486E+042.9454E+043.6621E+043.1134E+043.7848E+042.2054E+043.3569E+04
21222324252627282930
3.2711E+041.8926E+044.8014E+043.5212E+043.8204E+042.7096E+043.9511E+042.1456E+042.4023E+043.6770E+04
31323334353637383940
3.2601E+043.8330E+043.7943E+043.1210E+042.5815E+042.3642E+043.7308E+042.0577E+042.0519E+044.3865E+04

 经过排序后的蚁狮适应度 sorted_antlion_fitness:(利用 sort 函数升序排列)

12345678910
1.8926E+042.0519E+042.0577E+042.0789E+042.1456E+042.2054E+042.2502E+042.2776E+042.3642E+042.4023E+04
11121314151617181920
2.5782E+042.5815E+042.5871E+042.6423E+042.7096E+042.9454E+042.9961E+043.1134E+043.1210E+043.1453E+04
21222324252627282930
3.1682E+043.2601E+043.2711E+043.3569E+043.3678E+043.4530E+043.5212E+043.6621E+043.6770E+043.7308E+04
31323334353637383940
3.7848E+043.7943E+043.8204E+043.8330E+043.9170E+043.9511E+044.3865E+044.8014E+045.1486E+045.4611E+04

排序后的索引 sorted_indexes:

12345678910
223938628191073629
11121314151617181920
4355226158173413
21222324252627282930
13121209324163037
31323334353637383940
18332532112740231412

最后得到的精英蚁狮的适应度 Elite_antlion_fitness 为18926.1875069310 。(当然,每次运行的结果都不一样,因为初始位置为随机数)接着用轮盘赌算法选择蚁狮。

for i=1:size(ant_position,1)
    % 选择适应度更高的蚁狮,适应度高的蚁狮捕获蚂蚁的概率越高
    Rolette_index=RouletteWheelSelection(1./sorted_antlion_fitness);
    if Rolette_index==-1  
        Rolette_index=1;
    end
    
    % RA是通过轮盘赌的方式在选定的蚁狮周围随机行走
    RA=Random_walk_around_antlion(dim,Max_iter,lb,ub, Sorted_antlions(Rolette_index,:),Current_iter);
        
    % RE是随机游走的蚁狮精英(目前为止最好的蚁狮)
    RE=Random_walk_around_antlion(dim,Max_iter,lb,ub, Elite_antlion_position(1,:),Current_iter);
        
    % 根据公式计算出蚂蚁位置
    ant_position(i,:)= (RA(Current_iter,:)+RE(Current_iter,:))/2; % Equation (2.13) in the paper          
end

根据公式 A n t_{i}^{t}=\frac{R_{A}^{t}+R_{E}^{t}}{2} 进行精益化。

(其中 R^t_A 是在第 t 次迭代时轮盘选择的蚁狮随机游走,R^t_E 是第 t 次迭代时围绕精英的随机游走,Ant_{i}^{t} 表示第 i 只蚂蚁在第 t 次迭代的位置)

代码:

% You can simply define your cost in a seperate file and load its handle to fobj 
% The initial parameters that you need are:
%__________________________________________
% fobj = @YourCostFunction
% dim = number of your variables
% Max_iteration = maximum number of generations
% SearchAgents_no = number of search agents
% lb=[lb1,lb2,...,lbn] where lbn is the lower bound of variable n
% ub=[ub1,ub2,...,ubn] where ubn is the upper bound of variable n
% If all the variables have equal lower bound you can just
% define lb and ub as two single number numbers

% To run ALO: [Best_score,Best_pos,cg_curve]=ALO(SearchAgents_no,Max_iteration,lb,ub,dim,fobj)

function [Elite_antlion_fitness,Elite_antlion_position,Convergence_curve]=ALO(N,Max_iter,lb,ub,dim,fobj)

% Initialize the positions of antlions and ants
antlion_position=initialization(N,dim,ub,lb);
ant_position=initialization(N,dim,ub,lb);

% Initialize variables to save the position of elite, sorted antlions, 
% convergence curve, antlions fitness, and ants fitness
Sorted_antlions=zeros(N,dim);
Elite_antlion_position=zeros(1,dim);
Elite_antlion_fitness=inf;
Convergence_curve=zeros(1,Max_iter);
antlions_fitness=zeros(1,N);
ants_fitness=zeros(1,N);

% Calculate the fitness of initial antlions and sort them
for i=1:size(antlion_position,1)
    % antlions_fitness(1,i)=fobj(antlion_position(i,:)); 
    antlions_fitness(1,i)=sum((antlion_position(i,:)).^2); 
end

[sorted_antlion_fitness,sorted_indexes]=sort(antlions_fitness);
    
for newindex=1:N
     Sorted_antlions(newindex,:)=antlion_position(sorted_indexes(newindex),:);
end
    
Elite_antlion_position=Sorted_antlions(1,:);
Elite_antlion_fitness=sorted_antlion_fitness(1);

% Main loop start from the second iteration since the first iteration 
% was dedicated to calculating the fitness of antlions
Current_iter=2; 
while Current_iter<Max_iter+1
    
    % This for loop simulate random walks
    for i=1:size(ant_position,1)
        % Select ant lions based on their fitness (the better anlion the higher chance of catching ant)
        Rolette_index=RouletteWheelSelection(1./sorted_antlion_fitness);
        if Rolette_index==-1  
            Rolette_index=1;
        end
      
        % RA is the random walk around the selected antlion by rolette wheel
        RA=Random_walk_around_antlion(dim,Max_iter,lb,ub, Sorted_antlions(Rolette_index,:),Current_iter);
        
        % RA is the random walk around the elite (best antlion so far)
        RE=Random_walk_around_antlion(dim,Max_iter,lb,ub, Elite_antlion_position(1,:),Current_iter);
        
        ant_position(i,:)= (RA(Current_iter,:)+RE(Current_iter,:))/2; % Equation (2.13) in the paper          
    end
    
    for i=1:size(ant_position,1)  
        
        % Boundar checking (bring back the antlions of ants inside search
        % space if they go beyoud the boundaries
        Flag4ub=ant_position(i,:)>ub;
        Flag4lb=ant_position(i,:)<lb;
        ant_position(i,:)=(ant_position(i,:).*(~(Flag4ub+Flag4lb)))+ub.*Flag4ub+lb.*Flag4lb;  
        
        ants_fitness(1,i)=fobj(ant_position(i,:));        
       
    end
    
    % Update antlion positions and fitnesses based of the ants (if an ant 
    % becomes fitter than an antlion we assume it was cought by the antlion  
    % and the antlion update goes to its position to build the trap)
    double_population=[Sorted_antlions;ant_position];
    double_fitness=[sorted_antlion_fitness ants_fitness];
        
    [double_fitness_sorted I]=sort(double_fitness);
    double_sorted_population=double_population(I,:);
        
    antlions_fitness=double_fitness_sorted(1:N);
    Sorted_antlions=double_sorted_population(1:N,:);
        
    % Update the position of elite if any antlinons becomes fitter than it
    if antlions_fitness(1)<Elite_antlion_fitness 
        Elite_antlion_position=Sorted_antlions(1,:);
        Elite_antlion_fitness=antlions_fitness(1);
    end
      
    % Keep the elite in the population
    Sorted_antlions(1,:)=Elite_antlion_position;
    antlions_fitness(1)=Elite_antlion_fitness;
  
    % Update the convergence curve
    Convergence_curve(Current_iter)=Elite_antlion_fitness;

    % Display the iteration and best optimum obtained so far
    if mod(Current_iter,50)==0
        display(['At iteration ', num2str(Current_iter), ' the elite fitness is ', num2str(Elite_antlion_fitness)]);
    end

    Current_iter=Current_iter+1; 
end

RouletteWheelSelection.m

用轮盘赌算法选择蚁狮。用一组权重代表在一组中每个蚁狮被选中的概率,返回被选中的蚁狮的索引。例如:fortune_wheel ([1 5 3 15 8 1]),最有可能的结果是4(权重15)。

代码:

function choice = RouletteWheelSelection(weights)
accumulation = cumsum(weights);  % 计算权重总和

p = rand() * accumulation(end); % rand()生成0-1的随机数
chosen_index = -1;
for index = 1 : length(accumulation)
    if (accumulation(index) > p)
      chosen_index = index; % 被选中的概率最大
        break;
    end
end
choice = chosen_index;

Random_walk_around_antlion.m

由于蚁狮从坑的中心向外射沙,蚂蚁随机游走超球面的半径会自适应地减小:

c^{t}=\frac{c^{t}}{I}

d^{t}=\frac{d^{t}}{I}

lb=lb/(I); 
ub=ub/(I); 

其中 I 为比率,根据以下公式可以修改比率 I 的大小:

I=1; % 当 current_iter <= 0.1 * max_iter 时

% 当 current_iter > 0.1 * max_iter 时
if current_iter>max_iter/10
    I=1+100*(current_iter/max_iter);
end

if current_iter>max_iter/2
    I=1+1000*(current_iter/max_iter);
end

if current_iter>max_iter*(3/4)
    I=1+10000*(current_iter/max_iter);
end

if current_iter>max_iter*(0.9)
    I=1+100000*(current_iter/max_iter);
end

if current_iter>max_iter*(0.95)
    I=1+1000000*(current_iter/max_iter);
end

根据以下公式移动蚁狮位置:

\begin{array}{l} c_{i}^{t}=\text { Antlion }_{j}^{t}+c^{t} \\ d_{i}^{t}=\text { Antlion }_{j}^{t}+d^{t} \end{array}

if rand<0.5
    lb=lb+antlion; 
else
    lb=-lb+antlion;
end

if rand>=0.5
    ub=ub+antlion; 
else
    ub=-ub+antlion;
end

创建n次游走,并初始化向量 lb 和 ub:

X(t)=\left[0, \operatorname{cumsum}\left(2 r\left(t_{1}\right)-1\right), \text {cumsum}\left(2 r\left(t_{2}\right)-1\right), \ldots, \operatorname{cumsum}\left(2 r\left(t_{n}\right)-1\right)\right]

X_{i}^{t}=\frac{\left(X_{i}^{t}-a_{i}\right) \times\left(d_{i}^{t}-c_{i}^{t}\right)}{\left(d_{i}-a_{i}\right)}+c_{i}^{t}

for i=1:Dim
    X = [0 cumsum(2*(rand(max_iter,1)>0.5)-1)']; 
    %[a b]--->[c d]
    a=min(X);
    b=max(X);
    c=lb(i);
    d=ub(i);      
    X_norm=((X-a).*(d-c))./(b-a)+c; 
    RWs(:,i)=X_norm;
end

代码:

% This function creates random walks

function [RWs]=Random_walk_around_antlion(Dim,max_iter,lb, ub,antlion,current_iter)
if size(lb,1) ==1 && size(lb,2)==1 %Check if the bounds are scalar
    lb=ones(1,Dim)*lb;
    ub=ones(1,Dim)*ub;
end

if size(lb,1) > size(lb,2) %Check if boundary vectors are horizontal or vertical
    lb=lb';
    ub=ub';
end

I=1; % I is the ratio in Equations (2.10) and (2.11)

if current_iter>max_iter/10
    I=1+100*(current_iter/max_iter);
end

if current_iter>max_iter/2
    I=1+1000*(current_iter/max_iter);
end

if current_iter>max_iter*(3/4)
    I=1+10000*(current_iter/max_iter);
end

if current_iter>max_iter*(0.9)
    I=1+100000*(current_iter/max_iter);
end

if current_iter>max_iter*(0.95)
    I=1+1000000*(current_iter/max_iter);
end


% Dicrease boundaries to converge towards antlion
lb=lb/(I); % Equation (2.10) in the paper
ub=ub/(I); % Equation (2.11) in the paper

% Move the interval of [lb ub] around the antlion [lb+anlion ub+antlion]
if rand<0.5
    lb=lb+antlion; % Equation (2.8) in the paper
else
    lb=-lb+antlion;
end

if rand>=0.5
    ub=ub+antlion; % Equation (2.9) in the paper
else
    ub=-ub+antlion;
end

% This function creates n random walks and normalize accroding to lb and ub
% vectors 
for i=1:Dim
    X = [0 cumsum(2*(rand(max_iter,1)>0.5)-1)']; % Equation (2.1) in the paper
    %[a b]--->[c d]
    a=min(X);
    b=max(X);
    c=lb(i);
    d=ub(i);      
    X_norm=((X-a).*(d-c))./(b-a)+c; % Equation (2.7) in the paper
    RWs(:,i)=X_norm;
end

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不雨_亦潇潇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值