能量谷优化算法(Energy valley optimizer,EVO)是MahdiAzizi等人于2023年提出的一种新颖的元启发式算法,其灵感来自关于稳定性和不同粒子衰变模式的物理原理。
物理反应是指两个粒子或外部亚原子粒子碰撞产生新粒子。在宇宙中,绝大多数粒子被认为是不稳定的,除了那些无限期保持完整的稳定粒子。不稳定的粒子倾向于通过分解或衰变来释放能量,而各种类型的粒子的整体衰变率则有所不同。在衰变过程中,产生能量较低的粒子,而额外的能量通过发射过程产生。能量谷涉及基于其结合能和与其他粒子相互作用的粒子的稳定性。对多种现象的直接观察使专家们提取了一些有价值的模式来定义粒子的衰变。该领域最关键的挑战是通过考虑中子(N)和质子(Z)的数量以及N / Z比率来确定粒子的稳定性界限。N/Z ≈ 1 是指稳定、轻质的颗粒,而对于较重的颗粒,较大的 N/Z 值被视为稳定带。基于粒子的稳定水平,每个粒子倾向于通过移动其N / Z比并向稳定带或能量谷移动来增加其稳定性水平。在这方面,粒子的中子富集水平在这一作用中起着至关重要的作用。位于稳定性界限上方的富中子粒子经历衰变过程,需要如此多的中子来保持稳定。另一方面,贫中子粒子需要太少的中子来实现稳定性,倾向于经历电子捕获或正电子发射以向能谷或稳定带移动。
在衰变过程中,产生能量水平较低的粒子,同时释放出过多的能量。有三种类型的排放决定了具有不同稳定性水平的粒子的衰变过程。α(α)粒子表示与氦相同的致密且带正电的粒子。β(β)粒子是带负电的粒子,其特征是具有较高速度的电子。伽马(γ)射线代表具有较高能量水平的光子。这些类型的发射的整体行为在电场内部进行了说明,考虑到α粒子在很小程度上向负极板弯曲。相比之下,β粒子向正极板弯曲很大,电场不影响γ射线。根据所呈现的发射过程细节,有三种类型的衰变,称为α、β和伽马衰变,源自前面提到的发射类型。在α衰变中,确定α粒子的损失,其中N / Z比率中的N和Z值在每个发射过程中减少。在β衰变中,β粒子的喷射是一个问题,其中通过减少N和增加Z值来增加N / Z比。在伽马衰变中,涉及从激发粒子中省略具有较高能级的γ光子,而这种衰变模式不需要改变N / Z值。这些方面的示意图如图所示。
算法步骤如下:
算法的流程图如下:
在智能优化算法的性能比较过程中,经常会需要用到一些测试函数,进行算法的性能比较。虽然CEC测试函数已经更新到2022版,这里整理了早期常用的23组测试函数公式。在对EVO算法进行性能评估中,我们主要采用这23组测试函数公式。
23组测试函数被分类为单模态的基准测试函数,多模态的基准测试函数和复合基准测试函数:
单模态的基准测试函数
多模态的基准测试函数
复合基准测试函数
CEC测试结果(部分):
下面给出EVO算法的matlab代码:
%% Energy Valley Optimizer (EVO) source code - version 1.1
%% Paper: Azizi M., Aickelin U., Khorshidi H., Baghalzadeh M.
%% Energy valley optimizer: a novel metaheuristic algorithm for global and engineering optimization.
%% Scientific Reports, 13, 226 (2023). https://doi.org/10.1038/s41598-022-27344-y
%% Clear Workspace & Command Window
clc; clear all;
%% Problem Information
CostFunction = @(x) Sphere(x); % @ Cost Function
VarNumber = 10; % Number of variables;
VarMin = -10 *ones(1,VarNumber); % Lower bound of variable;
VarMax = 10 *ones(1,VarNumber); % Upper bound of variable;
%% General Parameters
MaxFes = 150000 ; % Maximum number of function evaluations
nParticles = 20 ; % Maximum number of initial candidates
%% Counters
Iter=0; % Iterations
FEs=0; % Function Evaluations
%% Initialization
Particles=[]; NELs=[];
for i=1:nParticles
Particles(i,:)=unifrnd(VarMin,VarMax,[1 VarNumber]);
NELs(i,1)=CostFunction(Particles(i,:));
FEs=FEs+1;
end
% Sort Particles
[NELs, SortOrder]=sort(NELs);
Particles=Particles(SortOrder,:);
BS=Particles(1,:);
BS_NEL=NELs(1);
WS_NEL=NELs(end);
%% Main Loop
while FEs<MaxFes
Iter=Iter+1;
NewParticles=[];
NewNELs=[];
for i=1:nParticles
Dist=[];
for j=1:nParticles
Dist(j,1)=distance(Particles(i,:), Particles(j,:));
end
[ ~, a]=sort(Dist);
CnPtIndex=randi(nParticles);
if CnPtIndex<3
CnPtIndex=CnPtIndex+2;
end
CnPtA=Particles(a(2:CnPtIndex),:);
CnPtB=NELs(a(2:CnPtIndex),:);
X_NG=mean(CnPtA);
X_CP=mean(Particles);
EB=mean(NELs);
SL=(NELs(i)-BS_NEL)/(WS_NEL-BS_NEL); SB=rand;
if NELs(i)>EB
if SB>SL
AlphaIndex1=randi(VarNumber);
AlphaIndex2=randi([1 VarNumber], AlphaIndex1 , 1);
NewParticle(1,:)=Particles(i,:);
NewParticle(1,AlphaIndex2)=BS(AlphaIndex2);
GamaIndex1=randi(VarNumber);
GamaIndex2=randi([1 VarNumber], GamaIndex1 , 1);
NewParticle(2,:)=Particles(i,:);
NewParticle(2,GamaIndex2)=X_NG(GamaIndex2);
NewParticle = max(NewParticle,VarMin);
NewParticle = min(NewParticle,VarMax);
NewNEL(1,1)=CostFunction(NewParticle(1,:));
NewNEL(2,1)=CostFunction(NewParticle(2,:));
FEs=FEs+2;
else
Ir=unifrnd(0,1,1,2); Jr=unifrnd(0,1,1,VarNumber);
NewParticle(1,:)=Particles(i,:)+(Jr.*(Ir(1)*BS-Ir(2)*X_CP)/SL);
Ir=unifrnd(0,1,1,2); Jr=unifrnd(0,1,1,VarNumber);
NewParticle(2,:)=Particles(i,:)+(Jr.*(Ir(1)*BS-Ir(2)*X_NG));
NewParticle = max(NewParticle,VarMin);
NewParticle = min(NewParticle,VarMax);
NewNEL(1,1)=CostFunction(NewParticle(1,:));
NewNEL(2,1)=CostFunction(NewParticle(2,:));
FEs=FEs+2;
end
else
NewParticle(1,:)=Particles(i,:)+randn*SL*unifrnd(VarMin,VarMax,[1 VarNumber]);
NewParticle = max(NewParticle,VarMin);
NewParticle = min(NewParticle,VarMax);
NewNEL(1,1)=CostFunction(NewParticle(1,:));
FEs=FEs+1;
end
NewParticles=[NewParticles ; NewParticle];
NewNELs=[NewNELs ; NewNEL];
end
NewParticles=[NewParticles ; Particles];
NewNELs=[NewNELs ; NELs];
% Sort Particles
[NewNELs, SortOrder]=sort(NewNELs);
NewParticles=NewParticles(SortOrder,:);
BS=NewParticles(1,:);
BS_NEL=NewNELs(1);
WS_NEL=NewNELs(end);
Particles=NewParticles(1:nParticles,:);
NELs=NewNELs(1:nParticles,:);
% Store Best Cost Ever Found
BestCosts(Iter)=BS_NEL;
% Show Iteration Information
disp(['Iteration ' num2str(Iter) ': Best Cost = ' num2str(BestCosts(Iter))]);
end
Eval_Number=FEs;
Conv_History=BestCosts;
Best_Pos=BS;
%% Objective Function
function z=Sphere(x)
z=sum(x.^2);
end
%% Calculate the Euclidean Distance
function o = distance(a,b)
for i=1:size(a,1)
o(1,i)=sqrt((a(i)-b(i))^2);
end
end