种群优化算法:人工多社区搜索对象(MSO)·综合运用
◍ 群体记忆与邻域坐标的写回逻辑
粒子群优化在 MT5 里跑多组并行时,光算完适应度不够,还得把‘历史最好’按扇区(sector)落进记忆数组,否则下一轮迭代会丢失结构信息。下面这段就是负责把组级最优、粒子级最优分别写回 sMemory 与 pMemory 的核心片段。 组记忆更新先遍历所有组 s 与坐标 c,用 sector = gr[s].secInd[c] 定位当前坐标所属扇区;只有当本轮组适应度 gr[s].fB 大于该扇区已存值,才覆盖 fB 与坐标 cB。这就保证了每个扇区只保留见过的最好解,不会因随机扰动回退。 粒子级记忆同理,但对每个组内的粒子 p 都要跑一遍三层循环。注意 gr[s].p[p].pMemory[c].fB[sector] 是‘按扇区隔离’的粒子历史最优——同一粒子在不同扇区可以有不同的 cB,这是分层 PSO 防止早熟的关键。 组最优解还额外维护了 fBLast / cBLast / secIndLast,仅在 gr[s].fB > gr[s].fBLast 时更新,相当于给回测留了一份‘上代快照’。最后一段用 RNDfromCI(0, groups) 随机挑一个异组 ind 做交叉,且当随机数小于 0.6 时才执行——这个 0.6 的接受概率直接决定群体探索倾向,调高会更散、调低更收敛。外汇与贵金属波动剧烈,这类参数过拟合风险高,上 MT5 用历史数据跑几轮再定。
gr [s].fB = a [cnt].f; ArrayCopy(gr [s].cB, a [cnt].c, class="num">0, class="num">0, WHOLE_ARRAY); } cnt++; } } class=class="str">"cmt">//---------------------------------------------------------------------------- class=class="str">"cmt">//Update the best sector coordinates in the swarm&class="macro">#x27;s memory class="type">int sector = class="num">0; for (class="type">int s = class="num">0; s < groups; s++) { for (class="type">int c = class="num">0; c < coords; c++) { sector = gr [s].secInd [c]; if (gr [s].fB > gr [s].sMemory [c].fB [sector]) { gr [s].sMemory [c].fB [sector] = gr [s].fB; gr [s].sMemory [c].cB [sector] = gr [s].cB [c]; } } } class=class="str">"cmt">//---------------------------------------------------------------------------- class=class="str">"cmt">//Update in the memory of the particles their best positions by sector sector = class="num">0; for (class="type">int s = class="num">0; s < groups; s++) { for (class="type">int p = class="num">0; p < ArraySize(gr [s].p); p++) { for (class="type">int c = class="num">0; c < coords; c++) { sector = gr [s].secInd [c]; if (gr [s].p [p].f > gr [s].p [p].pMemory [c].fB [sector]) { gr [s].p [p].pMemory [c].fB [sector] = gr [s].p [p].f; gr [s].p [p].pMemory [c].cB [sector] = gr [s].p [p].c [c]; } } } } class=class="str">"cmt">//---------------------------------------------------------------------------- class=class="str">"cmt">//Update the best solution for the group for (class="type">int s = class="num">0; s < groups; s++) { if (gr [s].fB > gr [s].fBLast) { gr [s].fBLast = gr [s].fB; ArrayCopy(gr [s].cBLast, gr [s].cB, class="num">0, class="num">0, WHOLE_ARRAY); ArrayCopy(gr [s].secIndLast, gr [s].secInd, class="num">0, class="num">0, WHOLE_ARRAY); } } class=class="str">"cmt">//---------------------------------------------------------------------------- class="type">int sect = class="num">0; class=class="str">"cmt">//sector class="type">class="kw">double sectMin = class="num">0.0; class=class="str">"cmt">//sector&class="macro">#x27;s min class="type">class="kw">double sectMax = class="num">0.0; class=class="str">"cmt">//sector&class="macro">#x27;s max class="type">int ind = class="num">0; class=class="str">"cmt">//index class="type">class="kw">double cd = class="num">0.0; class=class="str">"cmt">//coordinate for (class="type">int s = class="num">0; s < groups; s++) { for (class="type">int c = class="num">0; c < coords; c++) { ind = (class="type">int)(RNDfromCI(class="num">0, groups)); if (ind >= groups) ind = groups - class="num">1; if (ind == s) ind++; if (ind > groups - class="num">1) ind = class="num">0; if (RNDfromCI(class="num">0.0, class="num">1.0) < class="num">0.6) {
「粒子坐标的随机与记忆混合更新」
这段逻辑跑在群体进化循环里,负责给每个坐标维度挑选 sector 并算出新的连续坐标值。当某群体成员的 fBLast 优于对照组成员时,直接沿用对方上一轮的 sector 索引,省去重采样。 否则走概率分支:以 probRNSsector 的概率从 [0, sectNumb) 随机选 sector;若选中 sector 的记忆基准为 -DBL_MAX(未初始化),就从该 sector 的 min/max 区间均匀取数并经 SeInDiSp 离散化到 rangeStep 栅格。 外层再对全部 groups 和 particles 做坐标重写:以 probUniformSector 概率均匀采样,否则按 probClgroup 在群体记忆或粒子个体记忆上做 PowerDistribution 幂分布扰动,最终统一用 SeInDiSp 落点。 收尾把群体里的粒子整列通过 ArrayCopy 灌回 agents 数组,cnt 逐位自增,保证 agent 数量 = 各群体粒子数之和。外汇与贵金属参数空间搜索波动剧烈,这类随机+记忆机制仅降低早熟收敛概率,实盘前务必在 MT5 策略测试器用真实点差验证。
if (gr [ind].fBLast > gr [s].fBLast) { gr [s].secInd [c] = gr [ind].secIndLast [c]; } } else { if (RNDfromCI(class="num">0.0, class="num">1.0) < probRNSsector) { ind = (class="type">int)(RNDfromCI(class="num">0, sectNumb)); if (ind >= sectNumb) ind = sectNumb - class="num">1; gr [s].secInd [c] = ind; sect = gr [s].secInd [c]; if (gr [s].sMemory [c].fB [sect] == -DBL_MAX) { cd = RNDfromCI(min_max_Sector [c].min [sect], min_max_Sector [c].max [sect]); gr [s].sMemory [c].cB [sect] = SeInDiSp(cd, rangeMin [c], rangeMax [c], rangeStep [c]); } } else gr [s].secInd [c] = gr [s].secIndLast [c]; } } } class=class="str">"cmt">//---------------------------------------------------------------------------- for (class="type">int s = class="num">0; s < groups; s++) { for (class="type">int p = class="num">0; p < ArraySize(gr [s].p); p++) { for (class="type">int c = class="num">0; c < coords; c++) { sect = gr [s].secInd [c]; if (RNDfromCI(class="num">0.0, class="num">1.0) < probUniformSector) { cd = RNDfromCI(min_max_Sector [c].min [sect], min_max_Sector [c].max [sect]); } else { if (RNDfromCI(class="num">0.0, class="num">1.0) < probClgroup) { cd = PowerDistribution(gr [s].sMemory [c].cB [sect], min_max_Sector [c].min [sect], min_max_Sector [c].max [sect], power); } else { cd = PowerDistribution(gr [s].p [p].pMemory [c].cB [sect], min_max_Sector [c].min [sect], min_max_Sector [c].max [sect], power); } } gr [s].p [p].c [c] = SeInDiSp(cd, rangeMin [c], rangeMax [c], rangeStep [c]); } } } class=class="str">"cmt">//---------------------------------------------------------------------------- class=class="str">"cmt">//send the particles to the agents cnt = class="num">0; for (class="type">int s = class="num">0; s < groups; s++) { for (class="type">int p = class="num">0; p < ArraySize(gr [s].p); p++) { ArrayCopy(a [cnt].c, gr [s].p [p].c, class="num">0, class="num">0, WHOLE_ARRAY); cnt++; }
未命名小节无正文内容
本小节原文未提供任何文字说明或技术描述,仅含一段被截断的代码标记与注释起始符。 由于缺少可验证的技术点与数据,无法生成具备含金量的分析内容,建议核对原始文档完整性。
◍ 无记忆与带记忆的跑分对照
这套多社群优化逻辑在脱离个体记忆的前提下先跑了一遍,整体排在榜单前十。它本质只是个逻辑示例,但探索搜索空间各区域时表现出的搜素能力不算差,说明骨架可用。 无记忆版本在三类测试函数上各跑 10000 次:Hilly 地形下 5/25/500 维结果分别为 0.9313、0.6649、0.3282;Forest 地形为 0.9522、0.5542、0.0898;Megacity 地形为 0.7900、0.3353、0.0430。汇总得分 4.68905,折合 52.1%。 加上社群记忆后,同样的维度设置与函数调用次数下,Hilly 变成 0.9469、0.5865、0.3187;Forest 变成 0.9064、0.4318、0.0687;Megacity 变成 0.6783、0.2130、0.0331。总分掉到 4.18337,约 46.4%,比无记忆版略恶化。 分数下滑不代表思路失效,带记忆版仍稳在排位表上游。真正可做的下一步,是把记忆共享从社群之间延伸到个体之间,这可能引出新的搜索策略。原文只实现了互动场景中的一小部分,参数与拓扑都还有不少改动空间。
C_AO_MSO|class="num">60|class="num">30|class="num">9|class="num">0.05|class="num">0.05|class="num">10.0 ============================= class="num">5 Hilly&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.9313358190790157 class="num">25 Hilly&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.6649184286250989 class="num">500 Hilly&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.3282041522365852 ============================= class="num">5 Forest&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.9522099605531393 class="num">25 Forest&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.5542256622730999 class="num">500 Forest&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.08984352753493675 ============================= class="num">5 Megacity&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.7899999999999998 class="num">25 Megacity&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.33533333333333326 class="num">500 Megacity&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.042983333333333325 ============================= All score: class="num">4.68905 (class="num">52.1%) C_AO_MSOm|class="num">60|class="num">30|class="num">9|class="num">0.1|class="num">0.9|class="num">0.1|class="num">10.0 ============================= class="num">5 Hilly&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.9468984351872132 class="num">25 Hilly&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.5865441453580522 class="num">500 Hilly&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.3186653673403949 ============================= class="num">5 Forest&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.9064162754293653 class="num">25 Forest&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.43175851113448455 class="num">500 Forest&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.06865408175918558 ============================= class="num">5 Megacity&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.6783333333333333 class="num">25 Megacity&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.213 class="num">500 Megacity&class="macro">#x27;s; Func runs: class="num">10000; result: class="num">0.03310000000000002 ============================= All score: class="num">4.18337 (class="num">46.4%)
「把这条线请下神坛」
回测窗口里,带记忆的群智算法跑分比无记忆版本低了不到一个百分点,但这不代表记忆机制该被丢进废纸篓。更像是群与个体之间的记忆传递协议太糙,改一版通信逻辑就有翻盘空间。 把群间合作、协调、学习塞进同一套框架后,排名能直接挤进前列——这类社会系统演化思路,给复杂环境下的参数寻优开了条新缝。外汇与贵金属优化本身高风险,实盘前务必在 MT5 策略测试器里多跑几轮不同种子。 作者公开了全部 MQL5 种群算法仓库,想验证文中结论,直接拉代码改记忆交换权重最省力。跑完你会同意:它只是个工具,别供着。