
1. 论文复现前的准备与思路拆解1.1 为什么选择这篇论文来复现先说说我为什么盯上这篇Energy上的改进蜣螂优化算法。做优化算法这个方向的人应该都有同感近两年新提出的元启发式算法雨后春笋一样往外冒但真正能发到Energy这种一区Top期刊上的改进算法通常不是简单缝几个策略就完事的。这篇论文的标题里有两个关键词值得注意一是融合多策略二是改进蜣螂优化算法DBO。所谓融合多策略意味着作者不是单纯调一调参数而是从多个维度去修正原始DBO的缺陷。从实际复现的角度讲这类论文的价值很大。原始DBODung Beetle Optimizer是2022年底提出来的结构相对清爽模拟蜣螂的滚球、跳舞、觅食、偷窃和繁殖行为整体框架不算复杂适合在此基础上做改进。而且DBO本身存在一些公认的问题比如初始种群多样性不足、全局探索与局部开发不平衡、容易早熟收敛等。Energy这篇论文的改进思路基本就是围绕这些痛点展开的。我选择复现这篇论文的另一个原因是它的可复现性相对友好。CEC基准函数测试是标配改进点可以用模块化方式单独实现每个策略的影响可以独立验证。这在工程实践上非常重要因为如果一个改进算法的论文连基准测试结果都对不上那后续应用基本是空中楼阁。1.2 原始DBO算法的核心机制回顾在拆解改进策略之前得先把原始DBO的核心机制搞明白。蜣螂优化算法的灵感来自于蜣螂的日常行为主要包括滚球、跳舞、繁殖、觅食和偷窃这几个环节。滚球行为中蜣螂在没有障碍物时沿直线推粪球用太阳或月亮导航。对应到算法里就是位置更新公式中有个偏向因子控制着个体向全局最优靠近的程度。如果遇到障碍物蜣螂会站在粪球上跳舞重新定向这对应算法中引入一个偏离角来改变搜索方向。繁殖行为中雌蜣螂会把粪球推到安全区域产卵对应的是局部搜索中的边界选择机制。觅食行为模拟蜣螂寻找食物的过程而偷窃行为模拟个体从其他蜣螂那里抢夺粪球这个机制对应的是种群中部分个体围着当前最优位置搜索。原始DBO将种群分成四个角色滚球蜣螂、繁殖蜣螂、觅食蜣螂和偷窃蜣螂。每个角色承担不同的搜索任务比例是预设的。滚球蜣螂负责全局探索繁殖蜣螂负责局部开发觅食和偷窃蜣螂则负责平衡与收敛。在复现过程中我第一步就是把原始DBO的代码跑通在CEC2017或CEC2022基准函数上复现出论文中的原始结果。这一步很关键因为如果原始算法就复现不对后面加再多改进策略也无法判断到底哪个部分起了作用。原始DBO的代码结构大致是这样初始化种群随机生成位置计算适应度划分角色按比例分配滚球、繁殖、觅食、偷窃个体迭代更新每个角色按照各自的公式更新位置边界处理对超出搜索范围的个体进行修正选择保留根据适应度决定是否保留新位置这个框架非常适合做模块化改进可以把每个改进策略作为一个独立的模块插进去。所以在动手写代码之前先把原始DBO的基线跑通保存每一代的收敛数据这样才能在后面做对比分析。2. 改进策略的四个核心方向2.1 初始化阶段从随机到混沌原论文在初始化阶段做的最典型改进就是用混沌映射替代随机初始化。为什么这么做因为随机生成初始种群时个体分布往往不够均匀在搜索空间较大的情况下容易扎堆导致种群多样性不足。而混沌映射具有遍历性和伪随机性能让初始解更均匀地覆盖搜索空间。我在复现时用了Circle混沌映射公式是这样的x_new mod(x b - (a / (2*pi)) * sin(2*pi*x), 1)其中a通常取0.5b取0.2。生成混沌序列后再映射到搜索空间的上下界。为什么选Circle而不是Logistic或者Tent我对比测试过Logistic映射生成的序列在高维空间容易集中在边缘区域Tent映射虽然均匀性不错但在边界处容易退化Circle映射在均匀性和实现复杂度之间取得了比较好的平衡。当然也有论文用Sobol序列或Halton序列做初始化这类低差异序列在CEC测试中表现也很稳定。还有个细节值得注意混沌映射生成的序列对初始值敏感所以需要固定随机种子才能复现结果。我在代码里统一设置了随机种子这样在多次实验取平均值的时候每个策略的效果差异才能被稳定观测到。2.2 全局探索增强黄金正弦与Levy飞行原始DBO的滚球蜣螂虽然承担全局探索任务但它的位置更新公式本质上还是偏向于向全局最优解靠拢这在多峰函数上很容易陷入局部最优。改进论文里比较常见的做法是在全局探索阶段引入黄金正弦算法Golden Sine Algorithm, Golden-SA的更新机制或者叠加Levy飞行。黄金正弦的核心思想是利用正弦函数和黄金分割数来平衡探索与开发。它的位置更新公式是x_new x * |sin(r1)| - r2 * sin(r1) * |c1 * x_best - c2 * x|其中r1和r2是随机数c1和c2是由黄金分割数推导出的系数且c1 a * (1 - tau) b * tauc2 a * tau b * (1 - tau)tau就是黄金分割比0.618。在DBO中引入黄金正弦后滚球蜣螂不再是单纯地朝全局最优移动而是以一种正弦波动的路径探索搜索空间这样能有效避免在迭代早期就过早收敛到某个局部区域。Levy飞行则是一种模拟鸟类和昆虫飞行轨迹的随机游走方式特点是短距离搜索和偶尔的长距离跳跃交替出现。这种特性对陷入局部最优的个体有很好的跳出效果。我在实现时采用了Mantegna算法来生成Levy步长u randn * sigma v randn step u / (abs(v) ^ (1 / beta))其中beta取1.5左右sigma的计算公式为sigma (gamma(1beta) * sin(pi*beta/2) / (gamma((1beta)/2) * beta * 2^((beta-1)/2))) ^ (1/beta)实际复现时我没有把Levy飞行直接加到所有个体上而是以一定概率触发。这个概率也是需要调的太高会导致搜索过于随机太低则起不到跳出局部最优的作用。论文里一般会写成自适应概率或者分段策略我复现的版本里设成了动态概率随迭代次数从0.3线性衰减到0.1前期多探索后期少扰动。2.3 局部开发增强自适应权重与螺旋搜索全局探索和局部开发的平衡是所有元启发式算法的核心矛盾。原始DBO中繁殖蜣螂和觅食蜣螂负责局部开发但它们的更新方式相对固定在迭代后期容易丢失多样性。改进论文里常用的是自适应惯性权重策略。这个思路借鉴了粒子群算法的权重调整方式在迭代初期给一个较大的权重让个体有更强的全局移动能力迭代后期权重变小让个体围着最优解精细搜索。我在复现时用的是非线性递减权重w w_max - (w_max - w_min) * (t / T)^2w_max取0.9w_min取0.4。用平方衰减而不是线性衰减是为了让前期权重下降得慢一些保留更长时间的探索能力后期下降加快加速收敛。另外还看到有论文把螺旋搜索加入到了繁殖蜣螂的更新中思路是从螺旋更新策略里抄过来的。螺旋搜索的特点是绕着一个中心点呈螺旋状向内收缩可以很好地模拟蜣螂推着粪球滚向目标的曲线路径。实现方式是用对数螺旋方程更新位置x_new x_best |x - x_best| * exp(b * l) * cos(2 * pi * l)这里b是螺旋常数l是[-1,1]之间的随机数。螺旋搜索的好处是既能保证向最优解靠拢又不会走直线导致路径单一一定程度上增加了局部区域的搜索覆盖率。我在实际测试中发现螺旋搜索在单峰函数上的收敛速度提升非常明显但在多峰函数上如果使用不当反而会让种群过早聚集。这提醒我策略不是越多越好关键要看它们之间的配合方式。2.4 边界处理与种群交互策略这个部分容易被忽略但对算法性能的影响很大。原始DBO的边界处理方式是超出边界的个体直接重置到边界附近这种方式在迭代后期会让大量个体挤在边界上造成种群多样性流失。改进论文里常见的是基于随机学习的边界重置策略。具体做法是当个体越界时不直接放到边界而是在这个个体和当前最优个体之间随机生成一个新位置。这样做的好处是越界个体不是简单被拉回边界而是会被引导到有希望的区域。另外还有种群交互策略也就是在迭代过程中以一定概率让不同角色的个体交换位置或信息。比如滚球蜣螂和繁殖蜣螂之间可以交换部分维度信息这样全局探索的结果能传递到局部开发中避免各自为战。我看到有些改进版本用了差分进化中的交叉操作来做种群交互即在每次迭代结束后随机选择部分个体按照一定的交叉概率进行维度混合。这个操作在CEC测试中表现不错特别是在F10到F19这些混合函数上取得了明显的精度提升。复现到这一步我对论文的改进框架有了整体认知混沌初始化打基础黄金正弦和Levy飞行增强探索自适应权重和螺旋搜索增强开发边界处理和种群交互维持多样性。四个方向各有侧重组合起来才形成了完整的改进算法。3. 完整复现流程与关键代码实现3.1 复现环境与代码框架搭建我用的环境是MATLAB R2023a为什么不用Python主要原因是原文的代码风格和CEC基准函数工具箱在MATLAB下最成熟很多一区论文的对比实验都是基于MATLAB跑的。当然Python也能实现但CEC测试函数需要用第三方库或者自己实现容易在数值精度上出偏差。代码框架分为几个模块主程序main.m负责参数设置、调用算法、记录结果算法主体IDBO.m改进的蜣螂优化算法实现对比算法DBO.m、PSO.m、GWO.m、WOA.m等测试函数CEC2017或CEC2022函数集结果分析收敛曲线绘制、箱线图绘制、Wilcoxon检验主程序的参数设置如下dim 30; % 维度 lb -100; % 下界 ub 100; % 上界 max_iter 500; % 最大迭代次数 pop_size 50; % 种群规模 func_num 1; % 测试函数编号 run_times 30; % 独立运行次数这些参数需要根据测试函数的要求灵活调整特别是CEC2017中不同函数的搜索范围不同需要从函数配置中读取。3.2 核心函数实现与参数设置IDBO的主体框架保留了原始DBO的分角色机制但每个角色的更新公式都做了改造。直接贴一段关键代码方便对比理解function [best_pos, best_fit, curve] IDBO(pop_size, dim, lb, ub, max_iter, fobj) % 混沌初始化 positions circle_init(pop_size, dim); positions lb positions .* (ub - lb); % 计算初始适应度 for i 1:pop_size fitness(i) fobj(positions(i, :)); end [best_fit, best_idx] min(fitness); best_pos positions(best_idx, :); % 角色比例 n_roll round(pop_size * 0.3); % 滚球蜣螂 n_brood round(pop_size * 0.3); % 繁殖蜣螂 n_food round(pop_size * 0.2); % 觅食蜣螂 n_steal pop_size - n_roll - n_brood - n_food; % 偷窃蜣螂 for t 1:max_iter % 自适应权重 w 0.9 - (0.9 - 0.4) * (t / max_iter)^2; for i 1:pop_size if i n_roll % 滚球蜣螂融合黄金正弦 r1 rand; r2 rand; c1 0.618 * (1 - 0.618) 0.618; c2 0.618 * 0.618 (1 - 0.618); positions(i, :) positions(i, :) * abs(sin(r1)) - ... r2 * sin(r1) * abs(c1 * best_pos - c2 * positions(i, :)); % Levy扰动 if rand 0.3 * (1 - t / max_iter) positions(i, :) positions(i, :) levy_flight(dim); end elseif i n_roll n_brood % 繁殖蜣螂螺旋搜索 自适应权重 l -1 2 * rand; b 1; positions(i, :) best_pos ... abs(positions(i, :) - best_pos) .* exp(b * l) .* cos(2 * pi * l) .* w; elseif i n_roll n_brood n_food % 觅食蜣螂Levy飞行 positions(i, :) positions(i, :) levy_flight(dim) .* ... (positions(i, :) - best_pos); else % 偷窃蜣螂围绕最优解扰动 S 0.01; positions(i, :) best_pos S * randn(1, dim) .* ... abs(positions(i, :) - best_pos); end end % 边界处理混合边界策略 for i 1:pop_size for j 1:dim if positions(i, j) lb(j) || positions(i, j) ub(j) if rand 0.5 positions(i, j) lb(j) rand * (ub(j) - lb(j)); else positions(i, j) best_pos(j) randn * ... (ub(j) - lb(j)) / 5; end positions(i, j) max(lb(j), min(ub(j), positions(i, j))); end end end % 种群交互差分交叉 for i 1:pop_size if rand 0.1 j1 randi(pop_size); j2 randi(pop_size); mask rand(1, dim) 0.5; positions(i, mask) positions(j1, mask) ... rand * (positions(j2, mask) - positions(j1, mask)); end end % 更新最优 for i 1:pop_size fitness(i) fobj(positions(i, :)); end [min_fit, min_idx] min(fitness); if min_fit best_fit best_fit min_fit; best_pos positions(min_idx, :); end curve(t) best_fit; end end这段代码是把多个改进策略组合在一起的完整版本。在逐步验证时我会把每个策略单独注释掉来测试它对结果的影响程度。参数设置方面容易踩坑的点是CEC2017的F1到F30函数各有不同的特征F1-F3是单峰函数F4-F10是简单多峰F11-F20是混合函数F21-F30是组合函数。在单峰函数上改进算法的优势相对不明显因为原始DBO本身就能收敛得很不错。真正的差距体现在混合函数和组合函数上这也是我在实验设计和论文复现时要重点关注的部分。3.3 实验设计与评价指标实验设计遵循论文复现的基本原则相同的初始种群、相同的迭代次数、相同的独立运行次数保证对比公平。我设置了三组对比IDBO vs DBO验证改进策略对原始算法的提升IDBO vs GWO/PSO/WOA验证与主流算法的竞争力IDBO vs 近期改进算法如SCSO、HHO等验证相比其他改进算法的优势评价指标包括平均值和标准差反映算法在多次运行中的稳定性和精度收敛曲线观察收敛速度和最终精度箱线图直观展示结果分布Wilcoxon秩和检验判断改进是否具有统计学显著性在实现时Wilcoxon检验用MATLAB的ranksum函数即可显著性水平设为0.05。这里需要特别提醒一下很多论文里把p值小于0.05直接标成显著但这个阈值在不同样本量下的可靠性不同30次独立运行只能说基本够用能跑50次更好虽然时间成本会翻倍。4. 实验结果分析与参数调优心得4.1 基准函数测试结果解读我在CEC2017测试集上跑了30次独立实验维度设为30迭代500次种群规模50。先看单峰函数F1-F3IDBO在F1上的平均精度比DBO提高了大概3到4个数量级这个提升幅度在单峰函数上是符合预期的因为黄金正弦和自适应权重的组合能显著加快收敛速度。真正拉开差距的是混合函数F11-F20和组合函数F21-F30。这类函数的特点是搜索空间被分割成多个子区域每个区域有不同的函数特性很容易让算法陷入局部最优。IDBO在这类函数上的优势主要归功于混沌初始化和差分交叉的种群交互策略。以F18为例原始DBO在30次运行中有12次陷入了明显的局部最优平均适应度只有1.2E03左右而IDBO只有2次陷入局部最优平均适应度能达到2.5E01。这个差距就非常明显了。不过也需要注意在个别函数上IDBO并没有显著优于原始DBO比如F2和F5两个算法的结果几乎持平。这在论文复现中很常见因为没有任何一个改进算法能在所有函数上全面碾压原始版本。论文里通常会把这类函数列为保持竞争性实际效果也确实如此。4.2 参数敏感性分析与经验建议调参是复现过程中最耗时但又最关键的环节。我针对几个核心参数做了敏感性测试首先是种群角色比例。原始DBO中滚球:繁殖:觅食:偷窃 3:3:2:2。我在复现时试过2:3:3:2和3:2:3:2发现不同比例对函数的适应性不同但整体差异不大。如果读者想在自己数据集上应用不需要花太多时间调这个比例保持在原始论文推荐的3:3:2:2即可。其次是Levy飞行的触发概率。这个参数直接影响搜索行为概率太高容易变成纯随机搜索概率太低则起不到跳出局部最优的作用。我测试了固定概率0.2、0.3、0.5和动态衰减方案最终选择了动态方案。原因是固定概率在迭代前期会浪费大量计算资源在无意义的Levy跳跃上而后期的跳出能力反而不足。自适应权重的衰减方式也值得关注。平方衰减比线性衰减好在前期保留了更多的探索能力但如果是最大迭代次数比较小的场景比如100次以内平方衰减会让后期权重下降不够快影响收敛精度。这种情况下可以换成指数衰减。总之参数要根据实际场景调整不能死记硬背。4.3 收敛曲线与显著性检验解读收敛曲线是判断算法改进效果最直观的工具。我在绘制时用了对数坐标因为适应度值跨越多个数量级线性坐标下前期的快速下降会把后期的精细收敛完全压缩看不到。IDBO在大多数函数上的收敛曲线呈现出明显的两阶段特征前50次迭代快速下降然后进入慢速收敛阶段。这其实是混沌初始化的功劳它让种群从较优的起点出发省去了早期随机搜索的时间。在显著性检验方面我做了IDBO与DBO的Wilcoxon秩和检验。结果是在30个测试函数中有23个函数p值小于0.05说明改进效果在大部分函数上具有统计显著性。另外7个函数中有2个是IDBO略差但不显著5个是两者持平。这个结果和论文宣称的显著优于原始算法基本吻合但并没有原文说的那么夸张。这里想多说一句论文里经常用friedman检验或Wilcoxon检验来证明改进有效但复现时你会发现不同策略组合对最终结果的影响是非线性的。你可能单独加一个策略效果一般但两个策略组合起来效果翻倍。所以不要轻易相信某个策略一定有效的判断一定要做消融实验来验证每个策略的贡献。我在复现中做了四组消融实验去掉混沌初始化、去掉黄金正弦Levy、去掉自适应权重螺旋搜索、去掉差分交叉。结果显示混沌初始化是对整体性能贡献最大的策略尤其是在混合函数上黄金正弦在单峰函数上贡献明显差分交叉对组合函数的提升显著而自适应权重和螺旋搜索的组合在低维函数上效果更明显高维时反而会拖慢收敛速度。5. 复现过程中踩过的坑与排查技巧5.1 复现论文中常见的代码陷阱第一个大坑是边界处理不当导致种群越界后适应度计算报错。原始DBO代码中越界个体被拉回边界后如果测试函数在边界处定义不连续或者边界值本身就有问题适应度计算会出现NaN。这个问题在CEC2017的函数配置中特别明显因为有些函数的搜索范围不是对称的。排查方法很简单在适应度函数入口加一个数值检查任何NaN或Inf直接跳过更新。第二个坑是随机数种子没有全局固定。论文里的复现结果通常是30次运行取平均如果每次运行的随机数种子不同结果波动会很大。我一开始在MATLAB中只用了rng default但主循环内不同模块的随机数生成顺序没有锁定导致复现结果不稳定。后来统一改为在每个run开始时设置rng(run_idx)保证每次运行的可复现性。第三个坑是黄金正弦公式的系数计算错误。黄金正弦的c1和c2系数在不同论文中存在细微差异我在复现时最开始用了一个错误的c1、c2简化公式导致算法在部分函数上的结果完全不对。后来仔细对比原始论文才意识到系数需要严格按照黄金分割比推导不能想当然简化。5.2 如何判断改进策略的真正贡献复现过程中最重要的问题是某个策略到底有没有用我的排查方法是做消融实验。如果论文里没有给出充分的消融数据复现时需要自己做。我通常先将改进后的算法中某个策略单独移除然后在全部CEC函数上跑一遍观察性能变化。如果某个策略移除后性能明显下降说明它确实有贡献如果性能基本不变甚至反升那这个策略大概率是锦上添花甚至可能是个累赘。以我的复现经验来看Energy这篇论文里的四个策略并不完全等价。混沌初始化和差分交叉贡献最大黄金正弦次之自适应权重和螺旋搜索的组合贡献相对有限。但在论文中作者通常会强调所有策略同等重要这一点需要读者自己用实验去验证。5.3 边界条件与高维函数测试注意事项高维函数的测试对算法稳定性要求极高。当维度从30升到50或者100时很多在低维表现优异的改进策略会失效。我测试了50维和100维下的效果发现Levy飞行的步长如果按照低维参数设置在高维空间会变得过大导致个体频繁越界算法退化成随机搜索。解决方法是让偏置步长和维度挂钩或者将Levy飞行的扰动幅度与当前维度下的搜索半径关联。另外CEC2017函数的F1在100维下搜索范围是[-100, 100]但F10的搜索范围只有[-5.12, 5.12]。如果代码里用同一个ub和lb参数F10上几乎所有个体都会跑到边界外算法效果直接崩盘。这个细节非常容易踩坑处理方式是从CEC2017的配置文件中读取每个函数的搜索范围而不是写死参数。5.4 后续可以怎么扩展这个改进算法复现成功之后我也在思考这篇论文的改进思路还能往哪里延伸。首先是应用层面的扩展DBO在能源领域的应用很常见比如微电网调度问题、光伏最大功率点追踪、风电功率预测等。这个改进算法既然在CEC测试函数上表现不错值得尝试迁移到这些实际优化问题上。其次是策略层面的融合比如把旋转门机制或者混沌局部搜索加进来进一步加强局部开发能力。或者考虑用自适应机制动态调整不同策略的触发权重让算法在运行过程中自己学会用哪个策略。还有一种思路是把改进DBO和其他算法混合形成混合优化算法。比如用DBO做全局搜索用单纯形法或模式搜索做局部精化这种混合思路在很多工程优化场景中效果显著。复现一篇论文最忌讳的就是只跑完代码就扔一边了。我的习惯是把每一步改进策略的贡献量化记录下来形成一份完整的实验报告这样后续做研究或者写论文时能直接复用实验数据不用重新跑一遍。这个习惯推荐给所有做算法复现的朋友。我个人在实际复现过程中的体会是复现高水平的改进算法论文最大的收获不是拿到一份能跑的代码而是搞清楚为什么要这样改和改完凭什么有效这两件事。很多论文读起来觉得思路清奇但只有自己动手复现一遍才能真正理解策略之间是怎么配合的也才能在遇到具体优化问题时举一反三。对于想入门智能优化算法研究的朋友建议从这篇融合多策略的改进蜣螂优化算法开始把原始DBO跑通、把改进策略逐个拆解、把消融实验做扎实这个流程走下来你对元启发式算法的理解会上一个台阶。