哈里斯鹰优化算法 HHO (matlab代码,包含23个常用的基准测试函数)可直接运行效果如图所示
先看主函数骨架,参数设置够直白:
function [Rabbit_Energy,Rabbit_Location]=HHO(nfe_max,N,lb,ub,dim,fobj) % 输入参数: % nfe_max - 最大评估次数 % N - 种群数量 % lb/ub - 变量上下界 % dim - 维度 % fobj - 目标函数句柄 % 初始化种群 X=initialization(N,dim,ub,lb); Fitness=zeros(1,N); for i=1:N Fitness(i)=fobj(X(i,:)); end [Rabbit_Energy,idx]=min(Fitness); Rabbit_Location=X(idx,:); nfe = N;这里初始化阶段就带着点小技巧:每个个体随机撒网,立刻计算适应度。注意nfe这个计数器,后面每次评估都要更新,控制算法停止的关键。
核心迭代部分才是重头戏:
while nfe < nfe_max E1=2*(1-(nfe/nfe_max)); % 逃逸能量线性递减 for i=1:size(X,1) E0=2*rand()-1; E=E1*E0; if abs(E) >= 1 % 探索阶段 q = rand(); if q >= 0.5 X(i,:) = (ub-lb)*rand()+lb; % 全局随机游走 else X(i,:)=Rabbit_Location - rand().*abs(Rabbit_Location - 2*rand().*X(i,:)); end else % 开发阶段 r=rand(); if r>=0.5 && abs(E)<0.5 % 软围攻 Jump_strength=2*(1-rand()); X(i,:)= Rabbit_Location - E*abs(Jump_strength*Rabbit_Location - X(i,:)); else % 硬围攻 X(i,:)= (Rabbit_Location - mean(X)) - E*rand().*... (ub-lb)*rand()+lb; end end % 边界处理 Flag4ub=X(i,:)>ub; Flag4lb=X(i,:)<lb; X(i,:)=(X(i,:).*(~(Flag4ub+Flag4lb)))+ub.*Flag4ub+lb.*Flag4lb; % 更新最优 Fnew=fobj(X(i,:)); nfe=nfe+1; if Fnew<Rabbit_Energy Rabbit_Energy=Fnew; Rabbit_Location=X(i,:); end end end这段把猛禽捕猎的四个阶段浓缩在条件判断里:当|E|≥1时全局搜索,否则进入局部开发。特别留意E的计算方式——随着迭代次数增加,E1线性减小,导致算法后期更倾向于精细搜索。
测试函数咱们准备了23个经典基准函数,拿Rastrigin函数举个栗子:
function o = F1(x) o=sum(x.^2 - 10*cos(2*pi*x) + 10); end跑分的时候要注意维度变化对结果的影响,通常测试需要跑30次取平均值。调用方式也简单:
fhandle=@F1; dim=30; [bestX,bestF]=HHO(10000,50,-5.12,5.12,dim,fhandle);实际运行会发现,HHO在前期收敛速度极快,但后期容易在最优解附近震荡。这时候可以调整逃逸能量公式,比如把线性递减改成指数形式:
E1=2*(exp(-0.05*nfe/nfe_max)); % 修改能量递减方式这么一改,后期震荡明显减弱,适应度值还能再降个数量级。
最后说个实战技巧——处理高维问题时,在边界检查后加个扰动操作,能有效防止早熟:
if rand()>0.8 X(i,:)=X(i,:).*(1+0.01*randn(size(X(i,:)))); % 高斯扰动 end这招在100维以上的测试中效果拔群,谁用谁知道。