在这里插入图片描述


1.背景

2021年,Braik等人受到变色龙随着环境自适应变化以及寻找食物的动态行为影响,提出了变色龙优化算法(Chameleon Swarm Algorithm,CSA)。

2.算法原理

2.1算法思想

变色龙优化算法模拟了变色龙捕食过程,分为搜索食物-锁定食物-捕获食物三种阶段。

2.2算法过程

群体位置初始化:
y = l b + r a n d ∗ ( u b − l b ) y=lb+rand*(ub-lb) y=lb+rand(ublb)
其中, u b , l b ub,lb ub,lb分别代表变色龙上下位置边界。
搜索食物
y t + 1 i = { y t i + p 1 ( P t i − G t ) r 2 + p 2 ( G t − y t i ) r 1 r i ⩾ P p y t i + μ ( ( u b − l b ) r 3 + l b ) sgn ( r a n d − 0.5 ) r i < P p y_{t+1}^{i}=\begin{cases}y_t^{i}+p_1(P_t^{i}-G_t)r_2+p_2(G_t-y_t^{i})r_1&r_i\geqslant Pp\\y_t^{i}+\mu\big((ub-lb)r_3+lb\big)\text{sgn}(rand-0.5)&r_i<Pp\end{cases} yt+1i={yti+p1(PtiGt)r2+p2(Gtyti)r1yti+μ((ublb)r3+lb)sgn(rand0.5)riPpri<Pp
其中, P t , G t P_t,G_t Pt,Gt分别变色龙 i i i当前最优位置和变色龙群最优位置。
在这里插入图片描述
r i ≥ P p r_i \geq Pp riPp,表示变色龙进行局部探索;当 r i < p P r_i<pP ri<pP进行全局搜索。论文中解释了该公式,假设 P , G , R P,G,R P,G,R是仿射空间(欧式空间去掉了距离)三点, P , G P,G P,G两点构成线段中某一点 S S S可以由随机数 r 1 ∈ [ 0 , 1 ] r_1 \in[0,1] r1[0,1]度量:
S ( r 1 ) = r 1 P + ( 1 − r 1 ) G S(r_1)=r_1P+(1-r_1)G S(r1)=r1P+(1r1)G
这里,当 r 1 = 0 r_1=0 r1=0时,此时 S S S位于点 G G G处;当 r 1 = 1 r_1=1 r1=1时,此时 S S S位于点 P P P处。同理,点 S , R S,R S,R中某点 Q Q Q可以由随机数 r 1 ∈ [ 0 , 1 ] r_1 \in[0,1] r1[0,1]度量:
Q ( r 1 , r 2 ) = r 2 S + ( 1 − r 2 ) R Q(r_1,r_2)=r_2S+(1-r_2)R Q(r1,r2)=r2S+(1r2)R
也就是说,通过随机数 r 1 , r 2 r_1,r_2 r1,r2可以将点 P , R , G P,R,G P,R,G中任意一点表出,这里我们将 Q ( r 1 , r 2 ) ↔ y t + 1 i , R ↔ y t i , P ↔ P i t , G ↔ G t Q(r_1,r_2) \leftrightarrow y_{t+1}^{i}, R \leftrightarrow y_t^{i},P \leftrightarrow P_i^{t},G \leftrightarrow G_t Q(r1,r2)yt+1i,Ryti,PPit,GGt就可以将变色龙搜索空间进行表述。
这里,控制参数 μ \mu μ表示变色龙探索能力,这里采用了常用的幂指数控制:
μ = γ e ( − α t / T ) β \mu=\gamma e^{(-\alpha t/T)^{\beta}} μ=γe(αt/T)β
随着迭代次数 t t t增加, μ \mu μ不断减少,从而控制算法收敛。
锁定食物:
变色龙通过旋转眼睛锁定食物,论文给出了三维空间中向量平移和旋转推导。
在这里插入图片描述
锁定食物时位置更新:
y t + 1 i = y r t i ∗ y ‾ t i y_{t+1}^{i}=yr_{t}^{i}* \overline{y}_t^{i} yt+1i=yrtiyti
这里 y ‾ t i , y r t i \overline{y}_t^{i},yr_{t}^{i} yti,yrti分别指变色龙各维度平均值和旋转中心坐标。
{ y r t i = m × y c t i y c t i = y t i − y t i m = R ( θ , V → z 1 , z 2 → ) \begin{cases}yr_{t}^{i}=m \times yc_t^{i} \\ yc_t^{i} =y_t^{i}-{y}_t^{i} \\ m=R\Big(\theta,\overrightarrow{V}z_1,\overrightarrow{z_2}\Big) \end{cases} yrti=m×yctiycti=ytiytim=R(θ,V z1,z2 )
其中, y c t i , m yc_t^{i},m ycti,m分别代表定心坐标和旋转矩阵。
捕获食物
当变色龙靠近食物时,变色龙会进行攻击,速度更新为:
v t + 1 i = ω v t i + c 1 ( G t − y t i ) r 1 + c 2 ( P t i − y t i ) r 2 v_{t+1}^{i}=\omega v_t^{i}+c_1\left(G_t-y_t^{i}\right)r_1+c_2\left(P_t^{i}-y_t^{i}\right)r_2 vt+1i=ωvti+c1(Gtyti)r1+c2(Ptiyti)r2
其中, c 1 , c 2 c_1,c_2 c1,c2参数控制速度。参数 ω \omega ω更新为:
ω = ( 1 − t / T ) ( ρ ( t / T ) ) \omega=(1-t/T)^{(\rho\sqrt(t/T))} ω=(1t/T)(ρ( t/T))
位置随着速度变化为:
y t + 1 i = y t i + ( ( ν t i ) 2 − ( ν t − 1 i ) 2 ) / ( 2 a ) y_{t+1}^{i}=y_t^{i}+\left(\left(\nu_t^{i}\right)^2-\left(\nu_{t-1}^{i}\right)^2\right)/(2a) yt+1i=yti+((νti)2(νt1i)2)/(2a)
加速度 a a a为:
a = 2590 × ( 1 − e − l o g ( t ) ) a=2590\times\begin{pmatrix}1-e^{-log(t)}\end{pmatrix} a=2590×(1elog(t))
伪代码

在这里插入图片描述

3.代码实现

% 变色龙群算法
function [Best_pos, Best_fitness, Iter_curve, History_pos, History_best]=CSA(pop, dim, ub,lb, fobj, maxIter)
%input
%pop 种群数量
%dim 问题维数
%ub 变量上边界
%lb 变量下边界
%fobj 适应度函数
%maxIter 最大迭代次数
%output
%Best_pos 最优位置
%Best_fitness 最优适应度值
%Iter_curve 每代最优适应度值
%History_pos 每代种群位置
%History_best 每代最优个体位置
%% 初始化种群
for i = 1:dim
    chameleonPositions(:,i) = lb(i)+(ub(i)-lb(i))*rand(pop,1);
end
%% 计算适应度
fit=zeros(pop,1);
for i=1:pop
     fit(i,1)=fobj(chameleonPositions(i,:));
end
Iter_curve=zeros(1,maxIter); %记录每代最优值
fitness=fit; 
[Best_fitness,index]=min(fit);
chameleonBestPosition = chameleonPositions; %初始化变色龙群最优位置
Best_pos = chameleonPositions(index,:); %最优变色龙位置
v=0.1*chameleonBestPosition; %初始速度
v0=0.0*v;
%% 控制参数
rho=1.0;
p1=2.0;  
p2=2.0;  
c1=2.0; 
c2=1.80;  
gamma=2.0; 
alpha = 4.0;  
beta=3.0; 
%% 迭代
for t=1:maxIter
a = 2590*(1-exp(-log(t))); 
omega=(1-(t/maxIter))^(rho*sqrt(t/maxIter)) ; 
p1 = 2* exp(-2*(t/maxIter)^2);  
p2 = 2/(1+exp((-t+maxIter/2)/100)) ;        
mu= gamma*exp(-(alpha*t/maxIter)^beta) ;

% 搜索食物
for i=1:pop
    if rand>=0.1 % pP设置为0.1
        chameleonPositions(i,:)= chameleonPositions(i,:)+ p1*(chameleonBestPosition(i,:)-chameleonPositions(i,:))*rand()+... 
                     + p2*(Best_pos -chameleonPositions(i,:))*rand();
    else 
        chameleonPositions(i,:)= chameleonPositions(i,:)+mu*((ub-lb)*rand+lb)*sign(rand-0.50) ;
    end   
end 

% 捕获食物
     for i=1:pop            
        v(i,:)= omega*v(i,:)+ c1*(chameleonBestPosition(i,:)-chameleonPositions(i,:))*rand +.... 
               + c2*(Best_pos-chameleonPositions(i,:))*rand;        

         chameleonPositions(i,:)=chameleonPositions(i,:)+(v(i,:).^2 - v0(i,:).^2)/(2*a);
     end
    
  v0=v;
  
 %% 边界
 for i=1:pop
     if chameleonPositions(i,:)<lb
        chameleonPositions(i,:)=lb;
     elseif chameleonPositions(i,:)>ub
            chameleonPositions(i,:)=ub;
     end
 end
 
for i=1:pop
    
    ub_=sign(chameleonPositions(i,:)-ub)>0;   
    lb_=sign(chameleonPositions(i,:)-lb)<0;
       
    chameleonPositions(i,:)=(chameleonPositions(i,:).*(~xor(lb_,ub_)))+ub.*ub_+lb.*lb_;  
 
  fit(i,1)=fobj (chameleonPositions(i,:)) ;
      
      if fit(i)<fitness(i)
         chameleonBestPosition(i,:) = chameleonPositions(i,:); 
         fitness(i)=fit(i); 
      end
 end


[fmin,index]=min(fitness); 
if fmin < Best_fitness
    Best_pos = chameleonBestPosition(index,:);
    Best_fitness = fmin;
end

   Iter_curve(t)=Best_fitness; 
   History_pos{t} = chameleonPositions;
   History_best{t} = Best_pos;
end
 
ngPosition=find(fitness== min(fitness)); 
g_best=chameleonBestPosition(ngPosition(1),:);  % Solutin of the problem
Best_fitness =fobj(g_best);

end
%%
function answer = get_orthonormal(m,n)
if ( (nargin==2) && (m>n) && (isnumeric(m)*isnumeric(n)) )
    
elseif ( nargin==1 && isnumeric(m) && length(m)==1 )
    
    n=m;
    
else
   error('Incorrect Inputs. Please read help text in m-file.')
end


count=0;
while (count==0)
    A=rand(m);
    B=A'*A ;


    [P,D] = eig(B) ;

    if ((P'*P - eye(m))>eps) 
        % error, vectors not orthonormal, repeat the random matrix draw again
        count=0;
    else
        % we want the first n of these orthonormal columns
        answer=P(:,1:n) ;
        count=1;
    end


end
end

%%
function [chameleonPositions]=rotation(chameleonPosition, searchAgents, dim)
for i=1:searchAgents      
          if (dim>2) 
              xmax=1;xmin=-1;
              th=round(xmin+rand(1,1)*(xmax-xmin));
              vec=get_orthonormal(dim,2);
              vecA=vec(:,1);
              vecB=vec(:,2);
              theta=(th*rand()*180)*(pi/180) ;
              Rot = RotMatrix(theta,vecA, vecB) ;
             if (theta~=0)
                V=[chameleonPosition(i,:) ]; 
                V_centre=mean(V,1); %Centre, of line
                Vc=V-ones(size(V,1),1)*V_centre; %Centering coordinates

                Vrc=[Rot*Vc']'; %Rotating centred coordinates
%                 Vruc=[Rot*V']'; %Rotating un-centred coordinates
                Vr=Vrc+ones(size(V,1),1)*V_centre; %Shifting back to original location
                 chameleonPosition(i,:)=((Vr)/1); 
 
             end
         else
              xmax=1;xmin=-1;
              th=round(xmin+rand(1,1)*(xmax-xmin));
              theta=th*rand()*180*(pi/180);
              Rot = RotMatrix(theta);
              
               if (theta~=0)
                V=[chameleonPosition(i,:) ];  
                V_centre=mean(V,1); %Centre, of line
                Vc=V-ones(size(V,1),1)*V_centre; %Centering coordinates

                Vrc=[Rot*Vc']'; %Rotating centred coordinates
                Vr=Vrc+ones(size(V,1),1)*V_centre; %Shifting back to original location
                chameleonPosition(i,:)=((Vr)/1);
               end
          end
end  
   chameleonPositions=chameleonPosition;
end
%%
function R = RotMatrix(alpha, u, v)
if numel(alpha) ~= 1
   error('JSimon:RotMatrrix:BadInput1', ...
      'Angle of rotation must be a scalar.');
end

s = sin(alpha);
c = cos(alpha);

% Different algorithms for 2, 3 and N dimensions:
switch nargin
   case 1
      % 2D rotation matrix:
      R = [c, -s;  s, c];
      
   case 2
      if numel(u) ~= 3
         error('JSimon:RotMatrrix:BadAxis2D', ...
            '3D: Rotation axis must have 3 elements.');
      end
      
      % Normalized vector:
      u = u(:);
      u = u ./ sqrt(u.' * u);
            
      % 3D rotation matrix:
      x  = u(1);
      y  = u(2);
      z  = u(3);
      mc = 1 - c;
      R  = [c + x * x * mc,      x * y * mc - z * s,   x * z * mc + y * s; ...
            x * y * mc + z * s,  c + y * y * mc,       y * z * mc - x * s; ...
            x * z * mc - y * s,  y * z * mc + x * s,   c + z * z .* mc];
      
   case 3
      n = numel(u);
      if n ~= numel(v)
         error('JSimon:RotMatrrix:BadAxes3D', ...
            'ND: Axes to define plane of rotation must have the same size.');
      end
      
      % Normalized vectors:
      u = u(:);
      u = u ./ sqrt(u.' * u);
      
      % Care for v being orthogonal to u:
      v = v(:);
      v = v - (u.' * v) * u;
      v = v ./ sqrt(v.' * v);
      
      % Rodrigues' rotation formula:
      R = eye(n) + ...
         (v * u.' - u * v.') * s + ...
         (u * u.' + v * v.') * (c - 1);
      
   otherwise
      error('JSimon:RotMatrrix:BadNInput', ...
            '1 to 3 inputs required.');
end

end


优化问题
以CEC2005测试函数为例

clear,clc,close all
x = -32:0.1:32;
y = x;
L = length(x);
for i = 1:L
    for j = 1:L
        f(i,j) = fun([x(i) y(j)]);
    end
end
surfc(x, y, f, 'LineStyle', 'none', 'FaceAlpha',0.5);

% 设定变色龙群参数
pop = 50;
dim = 2;
ub = [32, 32];
lb = [-32, -32];
maxIter = 100;
fobj = @(x) fun(x);

% 求解
[Best_pos, Best_fitness, Iter_curve, History_pos, History_best] = CSA(pop, dim, ub, lb, fobj, maxIter);

在这里插入图片描述
在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐