注:该算法已按照智能优化算法APP标准格式进行整改,可直接集成到APP中,方便大家与自己的算法进行对比。
逃生算法(Escape algorithm,ESC),这是一种受人群疏散行为启发的元启发式算法。该算法受人群疏散行为的启发,用于解决现实案例和基准问题。ESC算法模拟疏散过程中人群的行为,将人群在探索阶段分为冷静、聚集和恐慌三组,反映不同层次的决策和情绪状态。冷静的个体引导人群走向安全地带,聚集型个体在不太安全的区域模仿他人,而恐慌型个体在最危险的区域做出不稳定的决定。这些模型允许ESC算法模拟人们在危及生命的情况下使用的各种自适应策略,将其转化为一个计算框架,可以更有效地解决复杂的优化问题。

该成果将于2024年11月发表在计算机领域2区SCI期刊“Artificial Intelligence Review”上。与经典算法相比,ESC在复杂优化问题中表现出色性能。

1.算法原理
(1)算法与种群
ESC旨在模拟紧急疏散期间的人群行为,其中个人必须在动态和不确定的环境中走向出口。ESC引入了精英池的概念,代表了表现最好的个人,他们象征着人群确定的潜在退出。该机制增强了算法深入探索解空间的能力,同时考虑多个方向,避免了局部最优。
ESC算法首先初始化一个聚类,每个聚类都用一个N维向量的表达式来描述:每一个都用D维向量来描述 。在j维上第i个个体的值由下式给出:
其中lbj和ubj分别代表第j维的下界和上界,保证了每个个体的初始位置在可行空间内是随机分布的。随机变量ri,j均匀分布在0 ~ 1之间,反映了疏散初始决策过程的随机性。
初始化总体后,使用适应度函数fi=f(xi)对每个个体的适应度f进行评估。然后根据适应度按升序对种群进行排序,并将顶部个体存储在Elite Pool E中,该参数表示群体找到的潜在安全出口的数量。
(2)恐慌指数与迭代过程
ESC算法对迭代过程进行建模,以反映疏散过程中人群行为的演变。该算法根据疏散过程中不同的行为反应,将个体的动作分为冷静、聚集或恐慌三类。
在每次迭代t开始时,恐慌指数P(t)的计算如下:
更混乱的行为。随着t从0到迭代次数T,该指数随时间减小,模拟人群对疏散环境的适应。
(3)探索
在探索阶段,当t≤T/2(T为算法的最大迭代次数,T为当前迭代次数)时,根据种群的适应度水平将其分为冷静组、聚集组和恐慌组。具体而言,将种群按适合度升序进行排序,并将个体按比例分为三组,冷静组c= 0.15,h = 0.35,p = 0.5。这种分层反映了疏散过程中人群中个体的不同反应,有些人保持冷静,有些人遵循群体行为,有些人则惊慌失措。
(4)冷静人群
冷静群体中的个体行为理性,向中心位置Cj移动,这代表了群体的集体决定:
其中,Cj是j维度中冷静群体的中心,计算为该维度中所有平静个体的平均值。Vc,j由下式定义:
二进制变量m1由伯努利分布决定,允许部分更新,它模拟了由于人群拥挤而未更新的维度部分。具体地说,生成m1时,它以相同的概率取值0或1。w1是一个自适应Levy权值,使用Levy分布来模拟勘探阶段的步长。下图显示了冷静群的更新过程。

(5)聚集群更新
聚集群个体遵循平静和恐慌群体的行为。他们的立场根据以下两方面的影响进行更新:
在这个等式中,xp,j是从恐慌组中随机选择的个体,代表了恐慌驱动运动的潜在方向。w2是另一个用于对应群的自适应Levy权重。向量vh,j由下式定义:
m2是一个二进制变量,通过与m1相同的机制生成。下图显示了聚集群的更新过程。

(6)恐慌群更新
受潜在出口和其他个体随机指示的影响,恐慌驱动型个体对解决方案空间的探索更加不规律:
其中,Ej是从精英池中随机选择的个体,代表了恐慌驱使的个体可能走向的可能出口。Xrand,j表示从总体中随机选择的个体,在恐慌驱动的运动中引入了随机性元素。向量vh,j由下式定义
下图显示了恐慌组的更新过程。

(7)开发阶段
当迭代超过T/2时,算法过渡到开发阶段,在此阶段所有个体都被认为是平静的。重点转移到基于迄今为止确定的最佳解决方案的微调位置。在这个阶段,个体通过靠近精英池的成员来优化自己的位置,精英池代表了可能的安全出口和在之前迭代中确定的最佳解决方案,以及从群体中随机选择的个体。这个过程模拟了人群逐渐向确定的最佳出口收敛。这一阶段的位置更新由下式给出。
在公式中,xi,j代表第i个体在j维度上的位置。Ej是精英池成员的位置,象征着可能的安全出口和迄今为止确定的最佳解决方案之一。其中,xrand,j是从总体中随机抽取的个体的位置。这允许个体通过靠近精英池成员和随机选择的个体来优化自己的位置,模拟人群逐渐趋同于确定的最佳出口。下图为探索阶段的种群更新示意图。

所提出的ESC算法伪代码如图所示。
所提出的ESC算法流程图如图所示。ESC结合了额外的结构化元素,如排序和权重更新,使其特别适用于复杂优化环境。

2.结果展示





3.MATLAB核心代码
%% 淘个代码 %%,获取更多代码% 逃生算法(Escape algorithm,ESC)
function [best_fitness, best_solution, Convergence_curve] = ESC(N, maxIter, lb, ub, dim,fobj)
% Initialize population
if max(size(lb)) == 1
lb = lb * ones(1, dim);
ub = ub * ones(1, dim);
end
population = repmat(lb, N, 1) + rand(N, dim) .* repmat((ub - lb), N, 1);
fitness = arrayfun(@(i) fobj(population(i, :)), 1:N);
[fitness, idx] = sort(fitness);
population = population(idx, :);
fitness1 = fitness(1);
eliteSize = 5;
fitness_history = zeros(1, maxIter);
best_solutions = population(1:eliteSize, :); % Initialize the elite pool with the number of eliteSize
beta_base = 1.5; % Base beta
t = 0;
mask_probability=0.5;
while t < maxIter
panicIndex = cos(pi / 2 * (t / (3 * maxIter)));
[fitness, idx] = sort(fitness);
population = population(idx, :);
a = 0.15;
b = 0.35;
% Update positions
populationNew = population;
if t / maxIter <= 1/2
for i = 1:N
% Sort and classify individuals
calmCount = ceil(round(a * N));
conformCount = ceil(round(b * N));
calm = population(1:calmCount, :);
conform = population(calmCount + 1:calmCount + conformCount, :);
panic = population(calmCount + conformCount + 1:end, :);
calmCenter = sum(calm, 1) / calmCount;
% Randomly select a panic individual
if size(panic, 1) > 0
randomPanicIndex = randi(size(panic, 1));
panicIndividual = panic(randomPanicIndex, :);
end
% Create a random binary mask to control which dimensions are updated
mask1 = rand(1, dim) > mask_probability; % mask_probability controls the probability
if i <= calmCount
% For the calm group
minCalm = min(calm);
maxCalm = max(calm);
randomPositionVector = minCalm + rand(1, dim) .* (maxCalm - minCalm);
weightVector1 = adaptive_levy_weight(beta_base, dim, t, maxIter);
% Apply the mask for partial dimension updates
populationNew(i, :) = population(i, :) + ...
mask1 .* (weightVector1 .* (calmCenter - population(i,:)) + ...
(randomPositionVector - population(i,:) + randn(1, dim) / 50)) .* panicIndex;
elseif i <= calmCount + conformCount
% For the herding group
minConform = min(conform);
maxConform = max(conform);
randomPositionVector = minConform + rand(1, dim) .* (maxConform - minConform);
weightVector1 = adaptive_levy_weight(beta_base, dim, t, maxIter);
weightVector2 = adaptive_levy_weight(beta_base, dim, t, maxIter);
mask2 = rand(1, dim) > mask_probability; % Apply the mask for partial dimension updates
populationNew(i, :) = population(i, :) + ...
mask1 .* (weightVector1 .* (calmCenter - population(i,:)) + ...
mask2 .*(weightVector2 .* (panicIndividual - population(i,:))) + ...
(randomPositionVector - population(i,:) + randn(1, dim) / 50) .* panicIndex);
else
% For the panic group
elite_idx = randi(eliteSize);
elite = best_solutions(elite_idx, :);
randomIndividual = population(randi(N), :);
weightVector1 = adaptive_levy_weight(beta_base, dim, t, maxIter);
weightVector2 = adaptive_levy_weight(beta_base, dim, t, maxIter);
mask2 = rand(1, dim) > mask_probability; % Apply the mask for partial dimension updates
randomPositionVector = elite + weightVector1 .* (randomIndividual - elite);
populationNew(i, :) = population(i, :) + ...
mask1 .* (weightVector1 .* (elite - population(i,:)) + ...
mask2 .*(weightVector2 .* (randomIndividual - population(i,:))) + ...
(randomPositionVector - population(i,:) + randn(1, dim) / 50) .* panicIndex);
end
end
else
% Second half: Differential with random individuals in the elite pool and random individuals in a population
for i = 1:N
elite_idx = randi(eliteSize);
elite = best_solutions(elite_idx, :);
random_idx = randi(N);
random_individual = population(random_idx, :);
weightVector1 = adaptive_levy_weight(beta_base, dim, t, maxIter);
weightVector2 = adaptive_levy_weight(beta_base, dim, t, maxIter);
mask1 = rand(1, dim) > mask_probability; % Apply the mask for partial dimension updates
mask2 = rand(1, dim) > mask_probability; % Apply the mask for partial dimension updates
populationNew(i, :) = population(i, :) + ...
mask1 .* (weightVector1 .* (elite - population(i,:)) + ...
mask2 .*(weightVector2 .* (random_individual - population(i,:))));
end
end
% boundary control
for i = 1:N
Flag4ub = populationNew(i,:) > ub;
Flag4lb = populationNew(i,:) < lb;
populationNew(i,:) = (populationNew(i,:) .* ~(Flag4ub + Flag4lb)) + ub .* Flag4ub + lb .* Flag4lb;
end
fitnessNew = arrayfun(@(i) fobj(populationNew(i, :)), 1:N);
for i = 1:N
if fitnessNew(i) < fitness(i)
population(i,:) = populationNew(i,:);
fitness(i) = fitnessNew(i);
end
end
[fitness, idx] = sort(fitness);
population = population(idx, :);
best_solutions = population(1:eliteSize, :);
[best_fitness, best_idx] = min(fitness);
best_solution = population(best_idx, :);
t = t + 1;
fitness_history(t) = best_fitness;
end
Convergence_curve = [fitness1, fitness_history];
end
function w = adaptive_levy_weight(beta_base, dim, t, maxIter)
beta = beta_base + 0.5 * sin(pi/2 * t / maxIter);
beta = max(min(beta, 2), 0.1);
sigma = (gamma(1 + beta) * sin(pi * beta / 2) / (gamma((1 + beta) / 2) * beta * 2^((beta - 1) / 2)))^(1/beta);
u = random('Normal', 0, sigma^2, [1 dim]);
v = random('Normal', 0, 1, [1 dim]);
w = abs(u ./ abs(v).^(1/beta));
w = w / (max(w) + eps);
end
4.参考文献
[1]Kaichen OuYanga, Shengwei Fub, Yi Chenc, Qifeng Caid, Ali Asghar Heidari, et al. Escape: An Optimizer based on crowd evacuation behaviors[J]. Artificial Intelligence Review, 2024.
完整代码获取
后台回复关键词:
TGDM817
1万+



被折叠的 条评论
为什么被折叠?



