news 2026/9/16 0:49:57

斑马算法ZOA的MATLAB实现与基准函数测试详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
斑马算法ZOA的MATLAB实现与基准函数测试详解

简介:斑马算法的MATLAB实现,涵盖算法初始化、主循环、目标函数评估与结果可视化等完整模块,适合需要求解多峰值或非线性复杂优化问题的研究人员、工程师及本科及以上学生直接使用或二次开发。该算法模拟斑马种群的社会等级与运动模式,在收敛速度和计算开销上具有较好平衡。压缩包共12个文件,内含8个m脚本、3张效果图片与1个asv备份文件,整体仅56KB,轻量易部署。主要函数功能明确:初始化文件负责建立斑马种群的位置、速度等参数,主文件控制迭代更新与最优解记录,目标函数文件支持多种测试函数验证寻优能力,绘图脚本用于绘制适应度收敛曲线,便于直观评估算法稳定性。代码包含测试数据与详细注释,可结合参数反演、函数寻优等场景改造扩展,也可作为算法对比或教学演示基础。已有108人学习下载,适合作为群体智能优化算法的入门参考或教学示例。

1. 斑马算法是什么,为什么值得用MATLAB复现

斑马算法(Zebra Optimization Algorithm,简称ZOA)是2022年前后提出的群智能优化算法,模拟斑马觅食和防御捕食者两类行为。它和粒子群、灰狼算法处在同一类框架里,但结构上多了一个“防御阶段”,把探索和开发拆得更明确。对MATLAB用户来说,斑马算法的吸引力在于参数少、向量化容易:核心更新公式只有两行,却能在局部收敛速度和全局搜索能力之间做动态取舍。很多人把代码下载下来跑一遍,发现结果和论文差距大,问题通常不在算法本身,而在边界修复、掩码向量生成或者测试预算设置上。这篇文章完整给出斑马算法的MATLAB实现,并在标准基准函数上验证测试效果,适合做优化算法复现、学术对比实验或工程参数寻优的人参考。读完可以直接把代码改成自己的目标函数。

2. 斑马算法的两类搜索行为与MATLAB代码骨架

2.1 觅食与防御:ZOA的两阶段位置更新

斑马算法的一次迭代由两个阶段组成,每个阶段对应一种生物行为。第一阶段是觅食,个体在“先锋斑马”的引导下向当前最优位置移动,这是整个算法的主要开发手段。位置更新公式常见写法是:

X_new = X + r .* (P - A .* X)

其中P表示当前种群最优个体的位置,r是[0,1]均匀随机数,A是随机生成的二进制掩码向量,每个维度上以一定概率取0或1。掩码向量是把“跟随最优”和“保留原值”混合起来的关键。如果不加A,X会被整体拉到P附近,所有维度同步变化,高维空间里容易出现“早熟收敛”;加上A后,一部分维度被最优位置替换,另一部分维度保持原位置,让个体在最优解邻域内仍有维度层面的探索空间。

第二阶段模拟斑马防御捕食者。算法为每个个体生成一个概率p,当p < 0.5时采用逃跑策略,斑马向全局最优方向移动;当p >= 0.5时采用攻击策略,从当前种群中随机挑选另一个体作为参照向它靠近。逃跑策略偏向开发,攻击策略偏向探索。随机参照个体可以打破种群趋同性,避免所有斑马都挤到同一个局部谷底。

2.1.1 觅食阶段为什么用掩码向量

掩码向量A的取值方式是rand(N, dim) < 0.5,也就是每个维度独立地以50%概率取0或1。这种设计保证个体在靠近最优解时不会所有维度同时发生大位移,而是类似遗传算法的按位交叉。实际使用中,可以把0.5换成0.7或0.3,调节“跟随最优”的维度比例。掩码比例越大,被最优位置影响的维度越多,开发能力越强;比例越小,保留的个人信息越多,探索能力越强。

2.1.2 防御阶段的两个分支在平衡探索与开发

从实现角度看,第二阶段的逃跑分支和攻击分支共享同一个公式骨架,只是参照个体Q不同。逃跑分支的Q取全局最优,攻击分支的Q取种群随机个体。这样设计的好处是不需要额外的速度变量或惯性权重,只靠分支选择就能实现搜索策略切换。要注意的是两个分支公式里的r1和r2应各自独立生成,不能共用一个随机矩阵,否则维度间的随机扰动相关性过强,会削弱搜索方向多样性。

2.2 MATLAB实现ZOA主循环的骨架

下面是一个可直接运行的ZOA主函数,输入目标函数句柄和边界条件,输出最优位置、最优值以及每次迭代的收敛记录。

function [best_x, best_f, conv] = ZOA(fun, dim, lb, ub, N, MaxIter) % ZOA 斑马优化算法主体 % 输入: % fun - 目标函数句柄,输入行向量返回标量 % dim - 决策变量维度 % lb,ub - 变量下界/上界,可为标量或向量 % N - 斑马种群规模,建议取 20~50 % MaxIter- 最大迭代次数 % 输出: % best_x - 全局最优位置 % best_f - 全局最优目标值 % conv - 每次迭代的最优值记录,用于画收敛曲线 % 1. 均匀随机初始化 X = lb + rand(N, dim) .* (ub - lb); fit = arrayfun(@(i) fun(X(i, :)), 1:N)'; % 记录初始最优 [best_f, idx] = min(fit); best_x = X(idx, :); conv = zeros(MaxIter, 1); for t = 1:MaxIter % ---------- 阶段一:觅食 ---------- A = rand(N, dim) < 0.5; % 二进制掩码向量 r = rand(N, dim); % 随机步长 forage = X + r .* (best_x - A .* X); forage = bound_repair(forage, lb, ub); f_forage = arrayfun(@(i) fun(forage(i, :)), 1:N)'; upd = f_forage < fit; X(upd, :) = forage(upd, :); fit(upd) = f_forage(upd); % ---------- 阶段二:防御捕食者 ---------- p = rand(N, 1); % 防御策略概率 A = rand(N, dim) < 0.5; r1 = rand(N, dim); r2 = rand(N, dim); Q = zeros(N, dim); for i = 1:N if p(i) < 0.5 Q(i, :) = best_x; % 逃跑:向最优靠拢 else pool = setdiff(1:N, i); % 攻击:随机选参照个体 Q(i, :) = X(pool(randi(length(pool))), :); end end defense = X + r1 .* (best_x - A .* X) + r2 .* (Q - A .* X); defense = bound_repair(defense, lb, ub); f_def = arrayfun(@(i) fun(defense(i, :)), 1:N)'; upd = f_def < fit; X(upd, :) = defense(upd, :); fit(upd) = f_def(upd); % 更新全局最优与收敛记录 [best_f, idx] = min(fit); best_x = X(idx, :); conv(t) = best_f; end end

代码里每个阶段都先按公式生成候选位置,然后用边界修复函数处理越界个体,最后用贪婪策略决定是否接受新位置。整体没有慢速循环,除了防御阶段里随机选个体的部分用了小循环,其余都是矩阵运算,在MATLAB里运行效率可以接受。

需要提醒的是,这里的边界修复函数bound_repair需要单独提供,下面是一个最简单的钳位版本。若把越界个体直接压到边界,会让边界处累积大量个体,影响多样性。后面会给出更稳妥的修复方式。

function Xb = bound_repair(X, lb, ub) Xb = max(min(X, ub), lb); end
2.2.1 运行前要确认的输入参数

主函数有六个输入量,作用如下表所示。理解每个参数的含义,是测试效果好坏的前提。

参数常用范围作用与影响
N20~60种群规模。过小容易早熟,过大会显著增加每次迭代的计算量
MaxIter100~1000迭代次数。高维测试函数建议不小于500
dim10~50决策变量维度。维度越高,对探索能力要求越高
lb / ub视函数而定搜索边界。对无约束优化,边界决定初始种群分布
fun任意标量函数目标函数句柄,必须支持行向量输入
best_x-初始最优位置,将参与第一阶段和逃跑分支的更新

如果目标函数对行向量和列向量敏感,建议在fun内部用x = x(:)';统一转成行向量,避免因维度不匹配报错或出现错误输出。参数N和MaxIter直接决定函数评价次数,也就是FES(Function Evaluations)。做算法对比时,必须保证不同算法的FES一致,否则结果不具备可比性。

3. 用标准测试函数跑通斑马算法的最小算例

3.1 三个基准函数:单峰、多峰、伪多峰

要判断斑马算法的测试效果,第一步不是直接上手工程问题,而是先在标准基准函数上验证。给出三个有代表性的函数:Sphere是单峰函数,Rastrigin布满局部极小值,Griewank则在高维空间中存在大量欺骗性局部结构。

函数名表达式搜索范围理论最优值
Spheresum(x.^2)[-100, 100]0
Rastriginsum(x.^2 - 10cos(2pi*x) + 10)[-5.12, 5.12]0
Griewank1 + sum(x.^2)/4000 - prod(cos(x./sqrt(1:numel(x))))[-600, 600]0

其中Rastrigin函数在三维以上的空间里会形成密集的等间距波峰波谷,是检验算法能否跳出局部最优的常客。Griewank在高维时局部极小值分布不像视觉上那么有规律,适合检验算法在“看似连续但存在大量局部陷阱”的曲面上的表现。

3.2 完整测试脚本与MATLAB调用方式

把三个基准函数写成函数句柄,再循环调用ZOA主函数,观察不同函数下的最优值、收敛曲线和稳定性。下面的脚本可以直接复制到MATLAB里运行。

clear; clc; rng(2024); % 定义测试函数 f_sphere = @(x) sum(x.^2); f_rast = @(x) sum(x.^2 - 10*cos(2*pi*x) + 10); f_griew = @(x) 1 + sum(x.^2)/4000 - prod(cos(x./sqrt(1:numel(x)))); % 统一参数 dim = 30; MaxIter = 500; N = 40; % 函数列表配置 problems = { f_sphere, -100, 100, 'Sphere'; f_rast, -5.12, 5.12, 'Rastrigin'; f_griew, -600, 600, 'Griewank' }; for k = 1:size(problems, 1) fun = problems{k, 1}; lb = problems{k, 2}; ub = problems{k, 3}; name = problems{k, 4}; [best_x, best_f, conv] = ZOA(fun, dim, lb, ub, N, MaxIter); fprintf('%s: best_f = %.6e\n', name, best_f); % 画收敛曲线 figure; semilogy(conv, 'LineWidth', 1.5); title([name, ' 收敛曲线']); xlabel('迭代次数'); ylabel('最优目标值'); grid on; end
3.2.1 三个测试函数的适配说明

在运行上面脚本之前,要注意各函数搜索范围的差异。Sphere的范围是[-100,100],Rastrigin是[-5.12,5.12],Griewank是[-600,600]。维度相同,范围不同,初始种群覆盖的体积差别很大。范围大的函数更适合检验算法在稀疏搜索空间中的探索能力;范围小的函数更容易出现边界附近个体扎堆的现象。建议三个函数分开设置lb和ub,不要统一取[-100,100],否则Rastrigin会被边界严重压缩。

另外,rng(2024)的作用是固定随机数种子。元启发式算法本质是随机算法,不固定种子,每次运行结果都会不一样。写论文或做测试效果分析时,必须在实验前固定随机种子,或在记录结果时保存每次运行的种子值。

3.2.2 边界修复方式的改进

前面给出的bound_repair只做钳位,长期运行会让边界附近积累大量个体。更推荐的两种方式如下,第一种是随机反弹,第二种是镜像反射。

% 方式一:随机反弹 function Xb = bound_random(X, lb, ub) Xb = X; mask = (X < lb) | (X > ub); Xb(mask) = lb + (ub - lb) .* rand(sum(mask(:)), 1); end % 方式二:镜像反射 function Xb = bound_mirror(X, lb, ub) Xb = X; Xb(Xb < lb) = 2 * lb - Xb(Xb < lb); Xb(Xb > ub) = 2 * ub - Xb(Xb > ub); end

随机反弹的优点是让越界个体回到搜索空间内任意位置,增加探索性;缺点是最优解在边界附近时容易把它弹走。镜像反射能把越界个体映射回边界内侧,同时又保持和边界的距离信息,适合目标函数最优解恰好落在边界附近的情况。我一般会默认使用bound_random,在工程问题中配合钳位一起用:先镜像反射,若仍越界再钳位。

4. 测试效果怎么量化:收敛曲线、寻优精度与对比实验

4.1 多次独立运行的统计指标

单次运行的最优值没有说服力。评估优化算法的测试效果,至少要记录多次独立运行后的最小值、平均值、标准差和成功率。标准差越小,说明算法对这个函数的求解越稳定;平均最优值离理论最优越近,说明精度和收敛能力越强。

M = 30; % 独立运行次数 F = zeros(M, 1); for run = 1:M [best_x, F(run), conv] = ZOA(f_sphere, dim, -100, 100, 40, 500); end success_rate = sum(F < 1e-8) / M * 100; fprintf('min = %.3e, mean = %.3e, std = %.3e, success = %.1f%%\n', ... min(F), mean(F), std(F), success_rate);

这段代码把30次运行的最优值单独存放,之后可以计算出统计指标。成功率以F小于1e-8为阈值,实际使用时可以根据问题精度要求调整。Sphere最优值是0,取1e-8作为成功标准比较合理;对Rastrigin或Griewank,若想观察是否收敛到全局最优,可以把阈值放宽松到1e-5。

统计结果最好保存到Excel或MAT文件里,方便后续画箱线图和做显著性分析。保存方式也比较简单,save('zoa_result.mat', 'F', 'conv')即可。

4.2 与经典算法的公平对比:函数评价次数是唯一标尺

斑马算法测试效果好不好,只看收敛曲线不够,还要和常用算法对比。常见的对比对象有粒子群算法(PSO)、灰狼算法(GWO)和鲸鱼算法(WOA)。这些算法迭代方式不同,不能直接按代数比,要比函数评价次数(FES)。FES = N × MaxIter。下面给出一个统一评价次数后的对比逻辑。

% 以FES=20000为例,不同算法用各自种群和迭代次数组合 FES = 20000; N1 = 40; MaxIter1 = FES / N1; N2 = 50; MaxIter2 = FES / N2; % 在相同FES下运行ZOA和PSO,并记录最优值 [~, F_zoa, ~] = ZOA(f_rast, dim, -5.12, 5.12, N1, MaxIter1); [~, F_pso, ~] = PSO(f_rast, dim, -5.12, 5.12, N2, MaxIter2); fprintf('ZOA: %.3e, PSO: %.3e\n', F_zoa, F_pso);

注意这里PSO需要额外实现速度更新和惯性权重,参数一般设置为w=0.729,c1=c2=1.494,这个组合是经典收敛性配置。对比实验至少要运行30次取平均值、标准差和箱线图,单次结果不能说明任何问题。

4.2.1 参数设置会给对比带来什么偏差

对比实验里最容易被问倒的问题就是参数来源。ZOA只有N和MaxIter两个控制参数,GWO也几乎没有额外参数;而PSO需要调惯性权重、个体学习因子和社会学习因子。如果PSO的参数设置不恰当,即使ZOA赢了也不能证明算法本身更好。为避免这种质疑,可以优先和参数同样少的GWO或WOA对比;若必须与PSO对比,需要在文中明确写出PSO的参数设置值并引用经典文献。另外所有算法应使用相同的边界修复方式,不能ZOA用随机反弹而PSO用钳位。

4.3 收敛曲线的画法与判读

MATLAB里画收敛曲线的最常用命令是semilogy,因为目标函数值往往跨越多个数量级。如果直接画线性坐标,早期下降过程会被压缩。绘制多条曲线对比时,要区分颜色和线型,并设置图例。

% 绘制ZOA、GWO、PSO三条收敛曲线于同一张图 iters = 1:500; figure; semilogy(iters, conv_zoa, 'b', 'LineWidth', 1.5); hold on; semilogy(iters, conv_gwo, 'r--', 'LineWidth', 1.5); semilogy(iters, conv_pso, 'k-.', 'LineWidth', 1.5); xlabel('迭代次数'); ylabel('最优目标值'); legend('ZOA', 'GWO', 'PSO', 'Location', 'northeast'); set(gca, 'YScale', 'log'); grid on;

判读收敛曲线有三个要点。第一,看前期的下降斜率,斜率大说明开发能力强;第二,看中后期是否存在长时间平台期,平台长且位置较高,说明陷入局部最优;第三,看曲线末尾是否还在下降,如果末端仍有明显下降趋势,说明迭代次数不够,可以延长MaxIter或增大种群规模。更严谨的做法是画出30次运行的平均收敛曲线和标准差阴影带,使用fill函数实现。阴影带越小,算法稳定性越强。

5. 参数敏感性、常见陷阱与斑马算法进阶改型

5.1 三个影响测试效果的关键设置

斑马算法整体参数少,但仍有几个容易被忽略的设置点。第一个是掩码向量A的生成概率,代码里默认用小于0.5作为阈值,直接把0.5改成0.7,相当于让更多维度跟随最优,收敛会加快,但探索能力会下降。第二个是是否使用贪婪选择。若把upd = f_forage < fit改成无条件更新,会给种群带来更大波动,适合多峰函数,但单峰函数上会拖慢收敛。第三个是边界修复方式,前文提过随机反弹和镜像反射的适用场景,建议在同一个测试集上统一用一种方式,否则不同算法之间会引入额外变量。

还有一个常见陷阱是目标函数内部写了disp打印语句。当FES达到几万次时,MATLAB的控制台打印会严重拖慢循环。可以把打印语句注释掉,或改用if mod(fes, 1000) == 0条件输出。

5.2 两个低成本改进方向

直接改公式就能见效的改进有两个。第一个是给觅食阶段引入线性递减惯性权重,模仿粒子群的做法,让前期多探索、后期多开发。

% 在ZOA主循环内部加入权重递减 w = 0.9 - 0.5 * (t / MaxIter); forage = X + w .* r .* (best_x - A .* X);

第二个是把ZOA和差分进化做简单混合:每迭代一定代数后,对种群做一次DE变异,变异个体如果适应度更优就替换原个体。这个操作成本低,但能显著改善多峰函数上的测试效果。

% 每10代执行一次DE/best/1变异 if mod(t, 10) == 0 mutant = best_x + 0.5 * (X(randperm(N,1),:) - X(randperm(N,1),:)); for i = 1:N trial = mutant(i, :); if fun(trial) < fit(i) X(i, :) = trial; fit(i) = fun(trial); end end end

做改进实验时,要保留原版ZOA作为baseline,控制变量只改一处,并在相同FES下比较30次结果,这样得出的结论才有说服力。改进方向能否落地,最终还是要回到目标函数上验证,建议先用低维、中维、高维三组同函数跑完,再替换成自己的工程目标函数,例如MATLAB优化工具箱里常见的约束问题。这样得到的测试效果才完整且可复现。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 0:48:22

技术品牌建设:从定位到运营的全流程指南

1. AlfredZhao项目概述AlfredZhao是一个典型的个人技术品牌建设项目&#xff0c;这类项目在技术社区中越来越常见。作为一名资深技术博主&#xff0c;我见过太多技术人尝试建立个人品牌&#xff0c;但真正能做到像AlfredZhao这样形成持续影响力的并不多见。这个项目的核心价值在…

作者头像 李华
网站建设 2026/9/16 0:46:54

软件卸载残留清理完整指南:注册表与AppData三步搞定

卸载软件这事&#xff0c;大多数人只完成了上半场。卸载程序确实把主文件删了&#xff0c;但注册表里的配置、AppData 里的缓存&#xff0c;往往原封不动躺在原地。你有没有遇到过这种情况&#xff1a;明明把某款软件卸载了&#xff0c;重装新版时却提示“已检测到旧版本&#…

作者头像 李华
网站建设 2026/9/16 0:46:51

ThinkBook 16 安装 Ubuntu 22.04 完整避坑指南

1. ThinkBook 16 这台机器到底“认不认” Ubuntu&#xff1f;先拆开 BIOS 看真章我第一次在 ThinkBook 16 上装 Ubuntu 22.04&#xff0c;不是从下载镜像开始的&#xff0c;而是从关机、按 F1 进 BIOS 设置界面开始的。这台机器出厂预装 Win11&#xff0c;表面看是“开箱即用”…

作者头像 李华
网站建设 2026/9/16 0:40:36

Stagehand:基于多模态理解的AI网页自动化框架

简介&#xff1a;Stagehand 是一个面向开发者与测试工程师的 AI 驱动型浏览器自动化框架&#xff0c;作为 Playwright 的轻量级继任者&#xff0c;专为自然语言驱动的 Web 自动化任务设计&#xff0c;适用于 AI 工程师构建智能爬虫、自动化测试脚本或低代码测试平台等场景。资源…

作者头像 李华
网站建设 2026/9/16 0:36:19

CentOS停更替代方案:Rocky Linux从零到KVM虚拟化实战指南

“CentOS还能用吗&#xff1f;”这是我近两年被问最多的一句话。如果你也是奔着这个问题点进来的&#xff0c;那我直接给结论&#xff1a;CentOS 8在2021年底就停止维护了&#xff0c;CentOS 7也将在2024年6月正式退役。对于跑业务的服务器来说&#xff0c;继续用等于裸奔。而R…

作者头像 李华