1. 文章摘要
海洋捕食者算法(Marine Predators Algorithm,MPA)是一种基于海洋生物捕食行为的智能优化算法。它通过模拟海洋生物在不同捕食阶段(追捕、群体协同、涡流效应等)中的位置更新策略,实现对搜索空间的全局和局部探索。该算法具有简单易实现、参数少且对复杂优化问题具有良好的收敛性能等优点。本文将详细介绍 MPA 的原理,并提供完整的 MATLAB 代码及其中文注释,帮助读者深入理解该算法的实现细节。
2. 算法介绍:Marine Predators Algorithm (MPA)
2.1 算法思路概述
MPA 算法主要模拟海洋捕食者(如鲨鱼、海豹等)在捕食过程中的行为与策略,并将其抽象为以下几个阶段:
-
初始化(Initialization)
- 随机生成一定数量的捕食者(搜索个体)的初始位置(解)。
- 计算它们的目标函数值(适应度),并记录当前全局最优解和最优适应度值。
-
海洋记忆机制(Marine Memory)
- 记录上一代捕食者的适应度和位置,若当前个体不优于上一代,则保留上一代的解。
-
捕食阶段(Predation phases)
- 阶段 1:前期捕食
- 使用**布朗运动(Brownian)**或随机飞行(Levy flight)等方式引导捕食者更新位置。
- 阶段 2:中期捕食
- 一部分捕食者尝试围绕全局最优解进行更新,另一部分结合随机扰动实现局部搜索。
- 阶段 3:后期捕食
- 进一步收敛至当前全局最优解,平衡局部开发与全局探索。
- 阶段 1:前期捕食
-
涡流效应(Eddy formation & FADs effect)
- 在一定概率下,引入相互交换或随机扰动,使得捕食者位置出现突变,以增强跳出局部最优的能力。
-
更新全局最优(Update Best)
- 计算每次迭代后所有个体的适应度值,更新全局最优解。
- 将最优解与其适应度存入收敛曲线,以便观察算法收敛过程。
2.2 算法优点
- 灵感来源于现实生物行为:具备一定生物多样性,提高解的多样性和搜索能力。
- 全局与局部结合:通过多个捕食阶段的策略切换,平衡全局与局部搜索。
- 记忆机制:保存上一代优良个体,可有效避免劣化,维持算法稳定性。
3. 源代码及中文详细注释
以下为 Marine Predators Algorithm (MPA) 的完整 MATLAB 代码:
% Marine Predators Algorithm source code (Developed in MATLAB R2015a)
% programming: Afshin Faramarzi & Seyedali Mirjalili
% paper:
% A. Faramarzi, M. Heidarinejad, S. Mirjalili, A.H. Gandomi,
% Marine Predators Algorithm: A Nature-inspired Metaheuristic
% Expert Systems with Applications
% DOI: doi.org/10.1016/j.eswa.2020.113377
function [Top_predator_fit,Top_predator_pos,Convergence_curve]=MPA(SearchAgents_no,Max_iter,lb,ub,dim,fobj)
% MPA 主函数
% 输入:
% SearchAgents_no: 种群规模 (海洋捕食者个体数)
% Max_iter: 最大迭代次数
% lb, ub: 搜索空间上下界 (可为标量或向量)
% dim: 问题的维度 (决策变量个数)
% fobj: 目标函数句柄
%
% 输出:
% Top_predator_fit: 最佳适应度 (全局最优的目标函数值)
% Top_predator_pos: 对应的最优解 (全局最优捕食者位置)
% Convergence_curve: 收敛曲线 (记录每次迭代的最优适应度)
Top_predator_pos = zeros(1,dim); % 存储当前全局最优捕食者位置
Top_predator_fit = inf; % 存储当前最优适应度值,初始化为无穷大
Convergence_curve = zeros(1,Max_iter); % 用于记录每次迭代的全局最优适应度
stepsize = zeros(SearchAgents_no,dim); % 存储捕食者位置更新时的步长
fitness = inf(SearchAgents_no,1); % 存储所有捕食者的适应度
%===================== 1. 初始化种群 (Prey) =====================%
Prey = initialization(SearchAgents_no,dim,ub,lb);
% Prey 为所有捕食者 (海洋生物) 的位置矩阵, 大小为 (SearchAgents_no x dim)
% 确保上下边界维度与 Prey 一致
Xmin = repmat(ones(1,dim).*lb,SearchAgents_no,1);
Xmax = repmat(ones(1,dim).*ub,SearchAgents_no,1);
Iter = 0; % 迭代计数器
FADs = 0.2; % 浮游物或渔具引起的扰动概率
P = 0.5; % 位置更新时采用随机步长的概率权重
%===================== 2. 开始迭代 =====================%
while Iter < Max_iter
%------------------- (A) 寻找当前最优捕食者 -----------------
for i = 1:size(Prey,1)
% 边界检查
Flag4ub = Prey(i,:) > ub;
Flag4lb = Prey(i,:) < lb;
Prey(i,:) = (Prey(i,:).*(~(Flag4ub+Flag4lb))) + ub.*Flag4ub + lb.*Flag4lb;
% 计算适应度
fitness(i,1) = fobj(Prey(i,:));
% 若当前个体优于全局最优,则更新
if fitness(i,1) < Top_predator_fit
Top_predator_fit = fitness(i,1);
Top_predator_pos = Prey(i,:);
end
end
%------------------- (B) 海洋记忆保存 (Marine Memory) -------------------
% 若当前个体适应度不如之前的,就保留之前的解,避免劣化
if Iter == 0
fit_old = fitness;
Prey_old = Prey;
end
Inx = (fit_old < fitness);
Indx = repmat(Inx,1,dim);
Prey = Indx.*Prey_old + ~Indx.*Prey; % 根据记忆进行选择
fitness = Inx.*fit_old + ~Indx.*fitness;
fit_old = fitness;
Prey_old = Prey;
%------------------- (C) 计算 CF,用于位置更新时的缩放 -------------------
Elite = repmat(Top_predator_pos,SearchAgents_no,1); % (Eq.10) 将全局最优解扩展成矩阵, 便于矢量运算
CF = (1 - Iter/Max_iter)^(2 * Iter/Max_iter); % 缩放因子, 随迭代进行调整
% 生成随机分布:Levy 飞行和正态分布 (Brownian)
RL = 0.05 * levy(SearchAgents_no,dim,1.5); % Levy 分布, 用于更新位置
RB = randn(SearchAgents_no,dim); % 正态随机数 (Brownian), 也用于位置扰动
%===================== 3. 捕食过程三个阶段 =====================%
for i = 1:size(Prey,1)
for j = 1:size(Prey,2)
R = rand();
%------------------ 第 1 阶段 (Eq.12) -------------------
if Iter < Max_iter/3
stepsize(i,j) = RB(i,j) * (Elite(i,j) - RB(i,j)*Prey(i,j));
Prey(i,j) = Prey(i,j) + P * R * stepsize(i,j);
%------------------ 第 2 阶段 (Eqs. 13 & 14) ------------
elseif Iter > Max_iter/3 && Iter < 2*Max_iter/3
if i > size(Prey,1)/2
% 后半部分个体采用布朗运动
stepsize(i,j) = RB(i,j)*(RB(i,j)*Elite(i,j) - Prey(i,j));
Prey(i,j) = Elite(i,j) + P * CF * stepsize(i,j);
else
% 前半部分个体采用 Levy 飞行
stepsize(i,j) = RL(i,j)*(Elite(i,j) - RL(i,j)*Prey(i,j));
Prey(i,j) = Prey(i,j) + P * R * stepsize(i,j);
end
%------------------ 第 3 阶段 (Eq.15) --------------------
else
stepsize(i,j) = RL(i,j)*(RL(i,j)*Elite(i,j) - Prey(i,j));
Prey(i,j) = Elite(i,j) + P*CF*stepsize(i,j);
end
end
end
%------------------ (D) 再次检测并更新全局最优 ------------------
for i = 1:size(Prey,1)
% 边界处理
Flag4ub = Prey(i,:) > ub;
Flag4lb = Prey(i,:) < lb;
Prey(i,:) = (Prey(i,:).*(~(Flag4ub+Flag4lb))) + ub.*Flag4ub + lb.*Flag4lb;
% 计算适应度
fitness(i,1) = fobj(Prey(i,:));
% 更新全局最优
if fitness(i,1) < Top_predator_fit
Top_predator_fit = fitness(i,1);
Top_predator_pos = Prey(i,:);
end
end
%------------------ (E) 海洋记忆保存,避免劣化 ------------------
if Iter == 0
fit_old = fitness;
Prey_old = Prey;
end
Inx = (fit_old < fitness);
Indx = repmat(Inx,1,dim);
Prey = Indx.*Prey_old + ~Indx.*Prey;
fitness = Inx.*fit_old + ~Indx.*fitness;
fit_old = fitness;
Prey_old = Prey;
%---------- (F) 涡流 (Eddy) 及 FADs 效应 (Eq.16) ----------
if rand() < FADs
% 情况1:在一定概率下,个体位置围绕随机生成的空间点变动
U = rand(SearchAgents_no,dim) < FADs;
Prey = Prey + CF*((Xmin + rand(SearchAgents_no,dim).*(Xmax-Xmin)).*U);
else
% 情况2:在另一定概率下,随机打乱个体位置形成大幅度迁移
r = rand();
Rs = size(Prey,1);
stepsize = (FADs*(1-r) + r)*(Prey(randperm(Rs),:) - Prey(randperm(Rs),:));
Prey = Prey + stepsize;
end
% 迭代计数器 +1
Iter = Iter + 1;
Convergence_curve(Iter) = Top_predator_fit; % 记录当前迭代最优值
end
end
%=========================== levy 函数 ===========================%
function [z] = levy(n,m,beta)
% levy 飞行: 产生满足 Levy 分布的随机向量
% 输入:
% n, m: 生成矩阵的维度
% beta: Levy 指数 (通常取 1.5)
%
% 输出:
% z: 尺寸为 (n x m) 的 Levy 随机数
num = gamma(1+beta)*sin(pi*beta/2); % 分子
den = gamma((1+beta)/2)*beta*2^((beta-1)/2); % 分母
sigma_u = (num/den)^(1/beta); % Levy 分布中的标准差
u = random('Normal',0,sigma_u,n,m);
v = random('Normal',0,1,n,m);
z = u./(abs(v).^(1/beta));
end
%=========================== initialization 函数 ===========================%
function Positions=initialization(SearchAgents_no,dim,ub,lb)
% 初始化捕食者种群
% 输入:
% SearchAgents_no: 个体数量
% dim: 维度
% ub, lb: 搜索空间上下界 (可为向量)
% 输出:
% Positions: 大小 (SearchAgents_no x dim) 的随机位置矩阵
Boundary_no= size(ub,2); % 检查边界是否是标量
% 如果上下界是单个数值
if Boundary_no==1
Positions=rand(SearchAgents_no,dim).*(ub-lb)+lb;
end
% 如果上下界是向量 (多维问题)
if Boundary_no>1
for i=1:dim
ub_i=ub(i);
lb_i=lb(i);
Positions(:,i)=rand(SearchAgents_no,1).*(ub_i-lb_i)+lb_i;
end
end
end
4. 总结
海洋捕食者算法(MPA)通过模拟真实海洋生物的捕食过程,将记忆机制与多阶段搜索策略相结合,在保持解多样性的同时不断提高搜索精度。此外,算法引入了涡流效应和布朗/Levy 飞行,为个体提供了跳出局部最优的机会。该算法简单易实现、适用性强,对于高维非线性优化问题也展现了良好性能。读者可在此代码基础上根据实际需求进一步扩展或改进,以应用到更多实际优化场景中。