ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

复现蝴蝶优化算法改进:Circle混沌初始化+非线性因子w,p,r+正余弦融合

复现蝴蝶优化算法改进:Circle混沌初始化+非线性因子w,p,r+正余弦融合 复现一篇蝴蝶优化算法BOA的改进论文标题写着“Circle混沌初始化种群非线性因子w、p、r融合正余弦算法”原以为照着摘要把公式抄下来就能跑出曲线结果断断续续折腾了一个多星期才真正把整套流程走通。这类组合型改进在智能优化领域非常典型基础算法优化能力不足就用混沌映射提升初始种群质量用动态参数调节探索与开发节奏再引入正余弦算法SCA增强局部搜索能力。单拎出来每一步都不难难的是让它们协同工作。这篇文章把我在复现过程中的拆解思路、数学推导补充、关键代码和踩坑记录都整理出来给正在做BOA改进或类似元启发式算法复现的朋友一个参考。1. 复现前必须拆清楚这篇BOA改进论文到底改了什么拿到一个标题就急着写代码是复现工作中最影响效率的做法。标题里几个词看起来各自独立实际上只有先把原始BOA的机制、三个改进点针对的缺陷、以及它们之间的联动关系摸清楚后面写代码才不会返工。1.1 原始BOA的三段式机制蝴蝶优化算法是Arora和Singh在2019年提出的元启发式算法核心思想是模拟蝴蝶觅食和求偶时对花蜜香味的感知。算法里每只蝴蝶是一个解每个解对应的适应度值被当作“刺激强度”I经过转换后成为该蝴蝶散发的“香味强度”ff c * I^a其中c是感觉因子a是模态指数。习惯上a取0.1c在迭代过程中从0.01逐渐增长到0.25。之所以让c递增是因为算法后期需要更大的香味吸引力来加快收敛。香味强度算出来后算法通过一个切换概率p决定当前蝴蝶执行哪个搜索分支全局搜索探索阶段x_i^(t1) x_i^t (r^2 * g* - x_i^t) * f_i局部搜索开发阶段x_i^(t1) x_i^t (r^2 * x_j^t - x_k^t) * f_i其中g*是当前全局最优解x_j和x_k是从种群中随机挑出的两个不同个体r是[0,1]均匀随机数。p在原始论文中固定为0.8也就是说每轮迭代中约80%的蝴蝶走全局搜索20%走局部搜索。从这套机制能看出原始BOA的设计逻辑蝴蝶通过香味感知全局最优位置并朝它靠拢这保证了全局搜索能力而随机挑选两个个体做线性组合则提供了一种简单的邻域扰动。但缺陷也很明显后面三个改进点几乎都是冲着这些缺陷去的。1.2 论文的三个改进方向分别补什么第一原始BOA的种群是纯随机初始化生成在解空间里分布不均匀容易导致初始种群离真实最优区域太远。标题里的“Circle混沌初始化种群”就是针对这一点用Circle混沌序列生成初始位置让种群在搜索空间里铺得更均匀。第二原始BOA的p固定为0.8、c固定增长、r使用均匀随机数都属于“静态”或“半静态”参数。标题里的“非线性因子w、p、r”是把三个关键参数都改成随迭代次数非线性变化的动态值让算法前期重探索、后期重开发。第三原始BOA的局部搜索结构过于简单只是两个随机解的差作为扰动方向精度有限。标题里的“融合正余弦算法”就是引入SCA的正弦余弦位置更新机制增强局部阶段的开采能力。1.3 编码前必须确认的四个问题在动手写代码之前建议先把下面四个问题落实清楚否则后续很容易推倒重来这篇论文用的测试函数是什么。CEC2017、CEC2019还是一般的Sphere、Rastrigin、Ackley决定了函数实现方式和结果统计口径。三个改进点各自的精确公式。特别是w和r不同论文有不同定义有的是惯性权重有的是随机系数方差要对照原文确认不要凭标题猜测。改进点之间是否有参数联动。比如p下降后进入局部搜索分支的概率变小此时SCA的混合比例是否也要跟着调整必须在写主循环前设计好。边界处理方式。混沌映射出来的值是否会被clip截断SCA的绝对值项是否会导致越界这些细节直接影响收敛行为。这四个问题都没有标准答案但提前想清楚能让复现过程更有针对性。论文复现不是抄答案而是把作者的思路转成可运行的代码过程中必然要补充原作者没有写明的细节。2. Circle混沌映射初始化公式与实现的数学细节混沌初始化在群智能优化里很常见但很多人只是随便套个公式没有理解映射的数学性质和实现时的参数选择问题导致初始化效果甚至不如随机生成。2.1 Circle映射公式与推荐参数Circle映射的迭代公式如下x_(n1) mod(x_n b - (a / 2π) * sin(2π * x_n), 1)其中a和b是控制参数。复现中最常用的组合是a0.5、b0.2这个组合下序列在[0,1]区间内具有较好的遍历性和低相关性。mod运算的作用是把结果拉回[0,1]区间保证混沌序列不发散。为什么选Circle而不是更常见的Logistic映射因为Logistic映射在参数接近4时虽然混沌但序列在0和1附近分布过密种群初始化后容易在边界堆积。Circle映射的均匀性相对更好尤其在维度较高时边界堆积造成的负面影响会更小。下面用一个表对比几种常用于初始化的混沌映射映射名称迭代公式均匀性实现复杂度常用参数Logisticx_(n1)μx(1-x)中等边界偏密最低μ4Tentx_(n1)min(x,1-x)*μ较好但易落入不动点低μ2Circlex_(n1)mod(xb-(a/2π)sin(2πx),1)较好序列均匀低a0.5, b0.2Chebyshevx_(n1)cos(k*arccos(x))中等波动大中k∈[2,6]2.2 从一维混沌序列到多维种群Circle映射生成的是[0,1]区间的一维序列但种群初始化需要的是一个pop_size×dim的矩阵。这里有两种映射方式方式一对每个维度独立生成一条混沌序列分别映射到搜索空间方式二只生成一条长序列然后按顺序切成多段填充给每个维度。实际复现时更推荐方式一因为方式二会让不同维度之间保持序列的连续性导致维度间相关性过强种群个体在搜索空间中对角线方向聚集。每个维度用不同的随机初值独立迭代得到的多维分布更接近均匀。实现代码如下import numpy as np def circle_chaos_sequence(x0, length, a0.5, b0.2, burn500): seq np.zeros(length) x x0 # 先迭代 burn 次跳过混沌映射的瞬态阶段 for _ in range(burn): x (x b - a / (2*np.pi) * np.sin(2*np.pi*x)) % 1 for i in range(length): x (x b - a / (2*np.pi) * np.sin(2*np.pi*x)) % 1 seq[i] x return seq def circle_initialization(pop_size, dim, lb, ub, a0.5, b0.2): X np.zeros((pop_size, dim)) for d in range(dim): x0 np.random.uniform(0, 1) seq circle_chaos_sequence(x0, pop_size, a, b) X[:, d] lb (ub - lb) * seq return X上面代码里有一个细节生成序列之前先迭代500次。因为混沌映射的初始段受初值影响较大分布不够稳定跳过这段瞬态能让进入种群的序列更均匀。这个操作在多数论文里不会写却是保证复现效果的重要一步。2.3 如何验证初始化真的变好了不要只凭经验说“混沌初始化有效果”要动手验证。一个常用的方法是计算初始种群的多样性度量比如平均成对欧氏距离或种群方差。以Sphere函数在[-100,100]^30空间、种群大小30为例随机初始化的种群适应度分布通常集中在1e4到1e5量级而Circle初始化后的种群适应度分布会更均匀地铺开最差个体的适应度往往会低一到两个数量级。另一个更直接的判断方式是看初始全局最优的适应度。多次独立运行后统计平均初始最优值如果Circle初始化的平均初始最优值明显优于随机初始化说明种子里确实有更接近最优区域的个体。后面正式跑收敛曲线时起点更低会让整个收敛曲线的外观更好看。3. 非线性因子w、p、r从固定值到动态设计的复现逻辑这部分是复现工作的重头戏。w、p、r三个字母在标题里并列出现但作用对象完全不同。很多复现稿把三个参数都简单改成随迭代递减结果算法后半段几乎停滞这就是没搞清楚每个参数在BOA搜索方程里的角色。3.1 固定参数到底限制了什么先看原始BOA里p固定为0.8的问题无论迭代早期还是后期都有大量蝴蝶执行全局搜索。理想情况下算法前期应该以探索为主通过大范围搜索捕捉全局信息后期应该转向开发对已有最优区域做精细搜索。p固定后后期仍然有大量蝴蝶跑去做全局大跳局部精化能力自然不够。再看感觉因子c。原始BOA中c从0.01线性增到0.25本质上是一种手动设定的动态策略。但c的作用并非简单越大越好因为它直接乘在香味强度上c过大会导致蝴蝶一步跳出几万个单位越过边界c过小又会吸附不动。另外随机数r的分布也会影响搜索步长的稳定性。3.2 惯性权重w的设计选择w在标题里的定位类似PSO中的惯性权重直接作用在位置更新式中的当前项上控制蝴蝶对自身位置的继承程度X_new w * X_current (r^2 * g* - X_current) * fw越大蝴蝶越倾向于保留原位置附近搜索越保守w越小当前位置的惯性越弱蝴蝶越容易被香味牵引到更远位置。复现中可以用抛物线递减w(t) w_start - (w_start - w_end) * (t / T)^2也可以使用余弦型衰减w(t) w_end (w_start - w_end) * cos(π * t / (2T))两种公式曲线形态不同抛物线递减在前期衰减慢、后期快适合那些需要长时间保持探索的测试函数余弦型衰减在早期下降略快能更快进入开发阶段。通常取w_start0.9、w_end0.4这两个值主要参考PSO经典参数组合。3.3 切换概率p的非线性策略p的改进应该是整篇论文里最容易出效果的修改点。原始p固定为0.8我复现时把它改为从0.9线性递减到0.3p(t) p_start - (p_start - p_end) * (t / T)前期p接近0.9大部分蝴蝶做全局搜索保证探索范围后期p降到0.3大部分蝴蝶转入局部搜索便于精细开发。这里要注意p的下限不要设置得太低否则后期几乎全部做局部搜索种群多样性会迅速耗尽容易早熟。也可以用正弦型策略让p先保持较大值一段时间再下降p(t) p_start - (p_start - p_end) * sin(π * t / (2T))正弦型策略在前期下降更慢对多峰函数的探索更友好线性策略简单直接对单峰函数收敛更快。具体用哪种要跟论文原稿保持一致如果论文没有明确写建议在代码里做成可配置项跑几次对比再确定。3.4 随机因子r的非线性设计原始BOA中r是[0,1]均匀随机数它在全局搜索里承担的是随机缩放的职责。改进版通常把r改成一个随迭代非线性递减的控制参数r(t) r_max - (r_max - r_min) * (t / T)^β这里β控制衰减曲线形态β1是线性β2是前期快后期平缓的凹曲线β0.5则相反。复现习惯上取r_max1.0、r_min0.1、β2。这样前期r较大允许蝴蝶大步跨越探索后期r较小限制步长只在最优解附近精细调整。此时全局搜索更新公式变成X_new w(t) * X_current (r(t)^2 * g* - X_current) * f把w、p、r三个动态参数放在一起看w管的是惯性取舍p管的是全局与局部搜索的分工比例r管的是单步步长尺度。三者协同后算法在迭代早期是一个“大步探索且偏全局”的状态迭代晚期变成“小步开发且偏局部”的状态这正是组合改进要达成的核心效果。下面给出一个参数配置表方便对照实现参数原始BOA改进策略推荐取值w无抛物线递减0.9 → 0.4p固定0.8线性/正弦递减0.9 → 0.3rU(0,1)随机幂函数递减1.0 → 0.1, β2c0.01→0.25线性保持不变0.01 → 0.25a0.1保持不变0.14. 正余弦算子与BOA的融合从公式到混合策略选择融合正余弦算法这一步最容易踩的坑是把SCA当成一个独立的算法步骤直接拼在BOA后面。正确理解应该是SCA提供了一种位置更新算子你可以把这种算子嵌入到BOA的某个分支里也可以让它以竞争候选的形式参与选择。4.1 SCA的更新公式与参数含义SCA的核心思想来自正弦和余弦函数的数学性质每个个体按下式更新X^(t1) X^t r1 * sin(r2) * |r3 * X_best - X^t| (r4 0.5) X^(t1) X^t r1 * cos(r2) * |r3 * X_best - X^t| (r4 0.5)其中r1 a - t * a / T控制搜索幅度随迭代线性递减r2 ∈ [0, 2π]控制移动方向r3 ∈ [0, 2]随机权重增强位置的随机性r4 ∈ [0, 1]决定使用正弦还是余弦分支。表面上看SCA和BOA都是朝最优解移动但区别在于SCA用正弦/余弦的周期交替特性可以让个体在靠近最优解时仍然产生振荡从而跳出局部极值。这个特性与BOA的随机扰动机制有本质差异。4.2 融合方式一让SCA接管局部搜索分支第一种实现方式很直接当p条件不满足时原本执行BOA局部搜索的蝴蝶改用SCA更新。这样全局分支保持BOA原有的探索机制局部分支换成正余弦振荡既能改善BOA原始局部搜索方向单一的缺陷又不会过度改变算法主体结构。if np.random.rand() p_t: # 全局搜索分支使用改进后的BOA更新 r_val r_t X_new w_t * X[i] (r_val * r_val * Gbest - X[i]) * f_i else: # 局部搜索分支使用SCA更新 r1 a_sca - t * (a_sca / T) r2 2 * np.pi * np.random.rand() r3 2 * np.random.rand() r4 np.random.rand() if r4 0.5: X_new X[i] r1 * np.sin(r2) * np.abs(r3 * Gbest - X[i]) else: X_new X[i] r1 * np.cos(r2) * np.abs(r3 * Gbest - X[i])这种方式实现简单、计算量小但注意SCA更新完全围绕全局最优Gbest如果Gbest本身陷入局部极值局部搜索也会跟着在局部区域震荡因此SCA的r1衰减速度要和BOA的动态参数保持节奏一致。4.3 融合方式二全局搜索阶段的双策略竞争第二种方式更精细在全局搜索分支中同时计算BOA的改进更新结果和SCA的更新结果然后比较两个候选解以及当前解的适应度选最优者作为新位置。这种方式不直接替换原有分支而是增加一个候选池决策权交给适应度函数。核心代码如下# 计算BOA全局更新候选 X_candidate_boa w_t * X[i] (r_t * r_t * Gbest - X[i]) * f_i f_candidate_boa func(X_candidate_boa) # 计算SCA更新候选 r1 a_sca - t * (a_sca / T) r2 2 * np.pi * np.random.rand() r3 2 * np.random.rand() r4 np.random.rand() if r4 0.5: X_candidate_sca X[i] r1 * np.sin(r2) * np.abs(r3 * Gbest - X[i]) else: X_candidate_sca X[i] r1 * np.cos(r2) * np.abs(r3 * Gbest - X[i]) f_candidate_sca func(X_candidate_sca) if f_candidate_boa f_candidate_sca and f_candidate_boa fitness[i]: X[i] X_candidate_boa fitness[i] f_candidate_boa elif f_candidate_sca f_candidate_boa and f_candidate_sca fitness[i]: X[i] X_candidate_sca fitness[i] f_candidate_sca双策略竞争的优点是不会过早丢失其中一种策略的探索能力理论上搜索能力更强缺点是每轮每个个体要计算两次目标函数计算量翻倍在CEC2017这种高维复杂函数上运行时间会明显增加。4.4 混合之后才需要关注的参数联动问题融合SCA后最容易被忽视的是r1的衰减与w、r两个参数的联动。w和r已经被设计成随迭代递减而SCA的r1也是线性递减三者叠加会让后期的搜索步长过小算法可能提前停止有效移动。解决方法是在SCA分支中不再乘w只保留r1控制步长或者在全局分支做双策略竞争时让SCA候选的r1使用单独的参数a_sca而不是复用w。我复现时的经验是BOA全局分支负责大范围寻优SCA分支负责局部振荡两者的步长机制最好保持独立。最简单的做法是给SCA单独设置一个a值例如a2并按原始SCA的线性递减公式计算r1不与w_t混用。5. 完整复现代码从混沌初始化到迭代主循环前面章节是理论拆解这一章给出可以直接跑起来的完整代码框架。我以Python为例测试函数先使用Sphere和Rastrigin你可以在此基础上扩展CEC系列函数。5.1 环境准备与测试函数实现需要安装的库只有numpy和matplotlib如果要跑Wilcoxon统计检验还需要scipy。测试函数实现如下import numpy as np def sphere(x): return np.sum(x ** 2) def rastrigin(x): A 10 return A * len(x) np.sum(x ** 2 - A * np.cos(2 * np.pi * x)) def ackley(x): a, b, c 20, 0.2, 2*np.pi d len(x) sum1 np.sum(x ** 2) sum2 np.sum(np.cos(c * x)) return -a * np.exp(-b * np.sqrt(sum1 / d)) - np.exp(sum2 / d) a np.exp(1)目标是统一的函数输入一维数组、输出适应度标量方便后续在主循环中批量计算。5.2 改进BOA-SCA算法的完整实现下面是结合前面所有改进点的主循环代码。要注意香味强度f的计算里有一个容易被忽略的归一化步骤我在代码注释里标了出来。def improved_boa_sca(func, dim, pop_size, max_iter, lb, ub): # 参数设置 w_start, w_end 0.9, 0.4 p_start, p_end 0.9, 0.3 r_max, r_min 1.0, 0.1 beta_r 2.0 c_start, c_end 0.01, 0.25 epsilon 1e-12 alpha 0.1 # 模态指数 a_sca 2.0 # SCA 控制参数 # Circle混沌初始化种群 X circle_initialization(pop_size, dim, lb, ub) fitness np.array([func(x) for x in X]) gbest_idx np.argmin(fitness) Gbest X[gbest_idx].copy() Gbest_fit fitness[gbest_idx] history [Gbest_fit] for t in range(max_iter): # 动态参数 w_t w_start - (w_start - w_end) * (t / max_iter) ** 2 p_t p_start - (p_start - p_end) * (t / max_iter) r_t r_max - (r_max - r_min) * (t / max_iter) ** beta_r c_t c_start (c_end - c_start) * (t / max_iter) # 对当前适应度做归一化避免香味强度数值爆炸 f_min fitness.min() f_max fitness.max() if f_max - f_min epsilon: norm_fit np.ones_like(fitness) else: norm_fit (fitness - f_min) / (f_max - f_min) epsilon for i in range(pop_size): # 香味强度 f_i c_t * (norm_fit[i] ** alpha) if np.random.rand() p_t: # 全局搜索分支BOA更新 SCA竞争候选 r r_t * np.random.rand() X_boa w_t * X[i] (r * r * Gbest - X[i]) * f_i X_boa np.clip(X_boa, lb, ub) f_boa func(X_boa) r1 a_sca - t * (a_sca / max_iter) r2 2 * np.pi * np.random.rand() r3 2 * np.random.rand() r4 np.random.rand() if r4 0.5: X_sca X[i] r1 * np.sin(r2) * np.abs(r3 * Gbest - X[i]) else: X_sca X[i] r1 * np.cos(r2) * np.abs(r3 * Gbest - X[i]) X_sca np.clip(X_sca, lb, ub) f_sca func(X_sca) if f_boa f_sca and f_boa fitness[i]: X[i] X_boa fitness[i] f_boa elif f_sca f_boa and f_sca fitness[i]: X[i] X_sca fitness[i] f_sca else: # 局部搜索分支使用SCA振荡更新 r1 a_sca - t * (a_sca / max_iter) r2 2 * np.pi * np.random.rand() r3 2 * np.random.rand() r4 np.random.rand() if r4 0.5: X_new X[i] r1 * np.sin(r2) * np.abs(r3 * Gbest - X[i]) else: X_new X[i] r1 * np.cos(r2) * np.abs(r3 * Gbest - X[i]) X_new np.clip(X_new, lb, ub) f_new func(X_new) if f_new fitness[i]: X[i] X_new fitness[i] f_new # 更新全局最优 cur_best_idx np.argmin(fitness) if fitness[cur_best_idx] Gbest_fit: Gbest X[cur_best_idx].copy() Gbest_fit fitness[cur_best_idx] history.append(Gbest_fit) return Gbest, Gbest_fit, history两个地方要特别说明。第一r的计算是在r_t基础上再乘一个随机数目的是保留原始BOA的部分随机性避免确定性递减导致算法变成纯梯度下降。第二香味强度计算前做了最大最小归一化这一步很多复现代码没有做但如果不做Ackley这类适应度范围非常大的函数很容易让f_i变成天文数字一次移动就把解弹到边界外。5.3 边界处理与精英保留策略我在这段代码里使用了np.clip直接截断越界个体。相比取模映射clip的优点是简单并且不会把解重新弹回搜索空间另一侧缺点是在边界附近会积累个体。对于大多数测试函数clip带来的影响可以忽略。还要注意Gbest本身并不会被clip操作触碰因为每次更新都是直接把X数组里最优个体的引用复制到Gbest不经过更新公式所以不存在最优个体被边界修改的问题。精英保留策略是算法稳定性的保障每一轮迭代结束时比较当前全局最优和历史最优只有当历史最优被更优解替代时才更新Gbest。这样能防止个别轮次出现适应度退化。5.4 统计结果输出格式复现论文光跑一次不够通常要运行30次独立实验统计收敛曲线平均值、最优值均值和标准差。输出示例测试函数原始BOA平均最优改进BOA-SCA平均最优改进最优值Sphere3.21e-051.04e-166.12e-21Rastrigin7.89e-011.54e-030.00e00Ackley1.04e-023.55e-052.11e-07这张表只是示意真实的数值取决于维度和迭代次数。重点是要养成记录完整统计结果的习惯而不是只展示某一次跑出的最好曲线。6. 复现踩坑实录验证方法、问题根因与调参建议最后这部分是整篇复现过程中最有价值的沉淀。很多坑不是你不知道公式而是公式实现出来之后结果不对又找不到原因。这里把几个常见问题按排查难度列出。6.1 怎么判断复现真的成功了建议按三步验证。第一步画出收敛曲线观察是否前期快速下降、中期平稳过渡、后期逐渐逼近最优如果曲线在中后期呈现完全水平甚至回升说明参数调节有问题。第二步跑30次独立实验统计最优值均值、标准差和中位数与原始BOA做对比。第三步做非参数检验常用Wilcoxon秩和检验计算p值是否小于0.05判断改进是否具有统计显著性。稳定性永远比单次最优值重要。一组好的复现结果应该是30次运行中几乎没有灾难性失败而不是某一次运气好跑出极小值。6.2 香味强度不归一化导致步长爆炸Ackley函数在[-32,32]区间内的适应度范围可能从0附近到超过20如果直接用f c * (fit^alpha)计算在适应度高的个体上香味强度会非常大。一次更新可能让解移动几十个单位直接越过边界。这是复现BOA时最容易踩的坑原始论文的符号推导没有问题但在数值实现时不做归一化很难复现出理想的收敛曲线。解决方式就是在主循环里对每一轮的适应度做最大最小归一化把刺激强度映射到接近[0,1]的区间。注意归一化后要加上一个极小量epsilon防止适应度差异为0时除零错误。6.3 Circle序列共用初值导致种群塌缩我一开始为了让代码简洁生成一条Circle混沌长序列后直接reshape成pop_size×dim的矩阵。结果发现高维函数上种群多样性反而变差原因是同一维度的序列与下一维度序列之间高度相关所有个体集中在解空间的一个狭长区域里算法收敛速度极慢。解决办法是对每个维度使用不同的随机初值并独立迭代也就是第2章代码里的实现方式。这个问题的特点是表象容易误导初始最优可能比随机初始化更好看但全局搜索能力被大幅削弱只有跑完整实验才能发现异常。6.4 p值衰减过猛导致早熟如果把p从0.9直接降到0.05后期几乎每只蝴蝶都在做局部搜索种群多样性快速耗尽在多峰函数上几乎必然陷入局部最优。复现时我把p_end设了0.2跑Rastrigin函数时30次实验有一半以上收敛到非零结果后来把p_end调回0.3才恢复正常收敛精度也提升了。参数下限的设置思路是确保局部搜索频率不会高到丧失种群多样性同时早期探索积累的信息足够支持后期开发。p_end在0.3左右通常是一个合理区间具体取值可以结合测试函数的多峰程度做敏感性实验。6.5 参数敏感性与推荐组合对w、p、r这类动态参数常见的做法是把起止值和衰减指数做小范围网格搜索。我实际运行后的推荐组合如下w0.9递减到0.4抛物线型对单峰和多峰函数都比较稳p0.9递减到0.3线性即可不需要过多归一化处理r1.0递减到0.1β2前期探索能力充足后期步长收敛c保持0.01到0.25线性增长a保持0.1这是BOA原论文的经典取值SCA的a值取2.0只控制SCA自身的搜索幅度不与w混用。这组参数在Sphere、Rastrigin、Ackley等常用函数上整体表现均衡。如果你在复现自己的论文建议先用这组参数跑通流程确认改进有效后再针对目标函数做细调不要一开始就盲目调参。整套复现走下来我最大的体会是组合改进最难的不是把三段代码拼在一起而是让三段改进的调性一致。Circle混沌初始化把种群铺得足够均匀w、p、r动态参数管的是搜索节奏的递进SCA加的则是局部阶段的一次模式切换三者需要协同发力而不是各自为政。如果你复现时结果始终上不去先别急着怀疑算法原理按这章的顺序检查归一化、种群初始化方式和参数衰减范围问题往往就藏在这几个细节里。
返回列表