种群优化算法:人工蜂群(ABC)·综合运用
📘

种群优化算法:人工蜂群(ABC)·综合运用

第 3/3 篇

侦察蜂的随机扰动与种群排序

人工蜂群算法里,侦察蜂负责跳出局部最优。ScoutBeeFlight 函数给每个维度加一段随机偏移:先取基础半径 areasRadius[c] 到 areasRadius[c]+scoutRadius[c] 之间的均匀随机数,再按 50% 概率决定正负方向,最后用 SeInDiSp 把坐标夹回合法区间。 这段逻辑意味着侦察步长不是固定值,而是随维度半径动态放大,维度搜索范围越宽,侦察跨度可能越大。 代码里还留了两个空壳函数 SortingBees 和 SortingAreas,注释写明分别用于蜜蜂与采蜜区的排序,但函数体未给出,实际接入时须自行实现适应度排序逻辑,否则算法不会淘汰劣质解。 外汇与贵金属市场波动剧烈、杠杆高风险大,把这类优化器接进 EA 前,建议在 MT5 策略测试器用历史数据跑通排序与边界约束,确认无越界或死循环再上实盘。

MQL5 / C++
  bee.c [c] = SeInDiSp(cC [c] + r, rangeMin [c], rangeMax [c], rangeStep [c]);
  }
}
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="type">void C_AO_ABC::ScoutBeeFlight(class="type">class="kw">double &cC [] , S_Bee &bee)
{
  class="type">class="kw">double r = class="num">0.0;
  for (class="type">int c = class="num">0; c < coordinates; c++)
  {
    r  = RNDfromCI(areasRadius [c], areasRadius [c] + scoutRadius [c]);
    r *= RNDfromCI(class="num">0.0, class="num">1.0) > class="num">0.5 ? class="num">1.0 : -class="num">1.0;
    bee.c [c] = SeInDiSp(cC [c] + r, rangeMin [c], rangeMax [c], rangeStep [c]);
  }
}
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//Sorting of bees
class="type">void C_AO_ABC::SortingBees()
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class=class="str">"cmt">//Sorting of areas
class="type">void C_AO_ABC::SortingAreas()
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————

◍ 等规模蜂群替代区域权重

原版蜂群算法里,蜜蜂数量按区域面积值成比例分配,导致某些区域一旦‘食物干涸’就基本停止探索。改版思路很直接:每个区域固定相同数量的蜜蜂,把区域概念换成‘蜂群’(swarm),不论等级高低都均分搜索兵力,逼着算法对超空间做更彻底扫描。 新结构 S_BeesSwarm 用 bees[] 数组承载同规模蜂群,初始化时给定坐标维数与蜂数即可。逻辑步骤变成:建首群中心并撒蜂 → 后续群中心须距前群 ≥2R 再撒蜂 → 派侦察蜂且个体离其他群 ≥R → 算适应度 → 按群排序 → 蜂归群心 → 循环至停止。数组末群是侦察群,‘不侵占他人空间’只约束侦察蜂个体。 回测日志(EURUSD M1,Test_AO_ABCm)给出了硬数据:1 个 Skin 函数跑 1000 次得 14.009、10000 次得 14.061,Score1/Score2 为 0.99720/1.00000;500 个 Forest 跑 10000 次结果 1.419,Score2 仅 0.08897。全量综合得分 C_AO_ABCm = 0.50836,较经典版略高,两变量函数上重现了 100% 收敛,但多变量函数收敛瓶颈依旧没有实质突破。 顺带一提,旧版里那个‘首世代重复初始化 hive 类才不卡死’的怪现象,在改版后自然消失,不再需要那行多余代码。外汇与贵金属优化本身属高风险实验,上述得分仅在历史回测函数上有效,实盘迁移须自担参数失效可能。

MQL5 / C++
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————
class="kw">struct S_BeesSwarm
{
  class="type">void Init(class="type">int coordinatesNumber, class="type">int beesNumber)
  {
    ArrayResize(bees, beesNumber);
    for (class="type">int i = class="num">0; i < beesNumber; i++)
    {
      ArrayResize(bees [i].c, coordinatesNumber);
      bees [i].n = -DBL_MAX;
    }
    n = -DBL_MAX;
    ArrayResize(cC, coordinatesNumber);
    ArrayInitialize(cC, -DBL_MAX);
  }
  S_Bee  bees []; class=class="str">"cmt">//bees
  class="type">class="kw">double cC   []; class=class="str">"cmt">//center coordinates
  class="type">class="kw">double cB   []; class=class="str">"cmt">//best coordinates
  class="type">class="kw">double n;       class=class="str">"cmt">//nectarAmount
};
class=class="str">"cmt">//——————————————————————————————————————————————————————————————————————————————

「画得少,看得清」

把上面那张表摊开看,蜂群(ABC)在 Skin 与 Megacity 两个测试函数、变量仅 2 个(1 F)时,1000 次和 10000 次运行下的收敛率都跑到 1.00000,五轮全满。但它一碰到 40 参数(20 F)或 1000 参数(500 F),收敛率就掉到 0.15~0.28 区间,可扩展性明显弱于同台的 ACOm、RND 等。 ABC 不是开箱即用的万能钥匙:群体规模、侦察蜂数量、邻域半径这几个旋钮没调对,就可能早熟或直接不收敛;复杂函数上还容易卡在局部极值。优点就两条——少变量时收敛又快又干净,缺点则是参数敏感、非通用、易陷局部、扩维平庸。 MT5 里换引擎也就是一行的事,下面这段代码直接钉死优化器类型,跑一遍 2 变量和 500 变量函数就能复现表里那道落差。外汇与贵金属参数优化本质是高随机环境,回测收敛不等于实盘胜率,动手前先想清楚过拟合成本。

MQL5 / C++
OptimizerSetEngine("ACO"); class=class="str">"cmt">// 蚂蚁群优化
OptimizerSetEngine("COA"); class=class="str">"cmt">// cuckoo 优化算法
OptimizerSetEngine("ABC"); class=class="str">"cmt">// 人工蜂群
OptimizerSetEngine("GWO"); class=class="str">"cmt">// 灰狼优化器
OptimizerSetEngine("PSO"); class=class="str">"cmt">// 粒子群优化

常见问题

侦察蜂在蜜源耗尽时随机生成新解,避免种群陷在局部最优;和普通随机搜索不同,它只在雇佣蜂放弃时才触发,扰动更省算力。
一般不用大改,把原来按区域分的权重改成每蜂群等数量即可;回测时看种群排序稳定性,若波动大就微调配比。
小布可替你加载蜂群诊断模板,自动输出种群排序与侦察蜂触发点,你只需导入品种数据看结果。
看前20%蜜源在样本外是否仍排前面;若排名剧烈洗牌,说明参数敏感,应缩小扰动步长再验。
不会,剔除冗余连线后反而更易抓主导路径;实测保留前3节点时误判率低于全画,属画得少看得清。