台球优化算法(BOA)
内容
引言
在优化算法的世界里,数学的精确性与现实世界的灵感相交汇,往往诞生出令人惊叹的巧妙方法。台球优化算法(BOA)就是其中之一,它从经典台球运动的力学机制中汲取灵感,构建其搜索策略。
想象一张台球桌,每一个球袋都代表一个潜在的解,而台球则是在可能性空间中移动的搜寻者。正如技艺高超的台球选手计算球的轨迹以将其精准送入袋中,BOA通过搜索和细化的迭代过程,引导其决策趋向最优结果。该算法由研究员 Hadi Givi 和 Marie Hubálovská 于 2023 年提出,展示了一种有趣且非同寻常的解决优化问题的方法。
在本文中,我们将深入探讨 BOA 的概念基础,剖析其数学模型,并分析其在解决多模态问题中的效率。该算法将概念的简洁性与数学的精确性相结合,在计算优化领域开启了新的视野,并成为现代优化方法库中有价值的补充。
算法的实现
BOA 算法是一种受台球运动启发的优化方法。想象一下,你正在寻找某个问题的最佳解,用台球术语来说,这就好比试图将球打入袋中。一张台球桌上有 8 个球袋,以及许多台球。在算法开始时,会生成一组随机解(种群)。这些决策就像台球桌上的球。针对每个解,计算其目标函数值,以确定其优劣。
在算法的每一次迭代中,种群中最好的八个解会成为“球袋”(即努力追求的目标)其余的解则被视为台球,需要被引导朝向这些球袋移动。对于每一个球(解),随机选择一个球袋(最佳解)。然后计算球的新位置——即一个朝向所选球袋移动的新解。如果球的新位置能提供更好的目标函数值,那么球就会移动到新位置;如果不能,则停留在原地。
从数学上看,它表示如下:
X_new = X + rnd [0.0; 1.0] × (P - I × X)
其中:
- X_new — 球的新位置,
- X — 球的当前位置,
- P — 球袋的位置(或当前球应该击中的球),
- I — 随机选取数字 1 或 2。
该过程会重复多次,最终球(解)应当趋近于问题的最优解。
BOA 的一个优势可能在于,理论上它仅需在方程中使用一个系数,就能很好地平衡全局搜索和局部搜索。这是通过使用随机比率 I 实现的,它确保球产生“未达到”(在优秀解附近细化解)或“超出”(探索解空间的不同区域)的效果。

图例 1. BOA 算法流程图
图 1 展示了 BOA 算法的工作原理示意图。中心元素是一个标记为“X”的白球,代表智能体在解搜索空间中的当前位置。在这个球周围是标记为“P”的彩色球——这些是代表迄今为止找到的 8 个最佳解的“球袋”或“孔”。示意图展示了智能体(白球)如何通过向不同的球袋移动来更新其位置,即在每一步中,智能体随机选择八个球袋中的一个作为移动的目标方向。
带箭头的橙色线条显示了智能体移动到不同球袋(在此例中为红色和蓝色球袋)的可能轨迹。虚线圆圈代表智能体移动时可能采取的中间位置,具体取决于 I 的值(1 或 2)。I 的值改变了“击球力度”和移动的性质:当 I=1 时,位置向所选球袋的方向偏移;当 I=2 时,智能体可以进行更剧烈的移动,这有助于探索解空间的更大一部分。
既然我们已经完全理解了算法的工作原理,我们将开始编写 BOA 伪代码。
初始化
确定球(种群)的数量 和球袋 的数量。
创建球(智能体)种群。
设置具有最小和最大边界的搜索空间。
基本算法
第一阶段:初始初始化(仅执行一次)
对于种群中的每个球:
在搜索空间中随机放置球。
保存其初始位置。
将适应度函数的初始值设置为最小值。
第二阶段:移动球
对于种群中的每个球:
对于球的每个坐标:
随机选择一个球袋(numPockets 个最佳解之一)。
使用以下方程更新球的位置:X_new = X + rnd [0.0; 1.0] × (P - I × X)
检查新位置是否保持在可接受的范围内。
第三阶段:更新最佳解
对于每个球:
如果球的适应度函数值优于全局最优,则更新全局最优。
如果球的适应度函数值优于其自身最优,则更新其自身最优。
按最佳适应度函数值对球进行排序。
排序后的前 numPockets 个智能体成为下一次迭代的球袋。
重复球移动和最佳解更新步骤,直到满足停止条件(例如,达到最大迭代次数)。
让我们开始编写算法代码。C_AO_BOA 类派生自 C_AO 类(种群优化算法的基类),并实现了 BOA 优化算法。让我们看一下它的关键元素:
- popSize 设置为 50,代表算法中球(智能体)的数量。
- numPockets 设置为 8,它构成台球桌上球袋的数量。
- params 数组的大小被改变,并且两个参数(popSize 和 numPockets)被添加到 params 数组中。
- SetParams () — 该方法负责将参数从 ‘params’ 数组设置回局部 popSize 和 numPockets 变量中。
- Init () — 初始化方法配置搜索的最小值、最大值和步长,以及设置 epoch(迭代周期)的数量。
- Moving () — 管理算法中球的移动。
- Revision () — 核实和修正智能体的位置/决策。
//—————————————————————————————————————————————————————————————————————————————— class C_AO_BOA : public C_AO { public: //-------------------------------------------------------------------- ~C_AO_BOA () { } C_AO_BOA () { ao_name = "BOA"; ao_desc = "Billiards Optimization Algorithm"; ao_link = "https://www.mql5.com/en/articles/17325"; popSize = 50; // number of balls (agents) numPockets = 8; // number of pockets on a billiard table ArrayResize (params, 2); params [0].name = "popSize"; params [0].val = popSize; params [1].name = "numPockets"; params [1].val = numPockets; } void SetParams () { popSize = (int)params [0].val; numPockets = (int)params [1].val; } bool Init (const double &rangeMinP [], // minimum values const double &rangeMaxP [], // maximum values const double &rangeStepP [], // step change const int epochsP = 0); // number of epochs void Moving (); void Revision (); //---------------------------------------------------------------------------- int numPockets; // number of pockets (best solutions) private: //------------------------------------------------------------------- }; //——————————————————————————————————————————————————————————————————————————————
C_AO_BOA 类中的 Init 方法负责初始化 BOA 算法。在方法开始时,会调用 StandardInit() 函数,并将最小值、最大值数组以及步长传递给它。该函数负责执行所有优化算法派生类必须执行的通用操作和初始化(包括初始范围的设置),以及准备算法中的底层搜索智能体。如果 StandardInit() 返回 ‘false’(初始化失败),Init 方法也会返回 ‘false’。如果一切顺利,该方法返回 ‘true’。
//—————————————————————————————————————————————————————————————————————————————— //--- Initialization bool C_AO_BOA::Init (const double &rangeMinP [], const double &rangeMaxP [], const double &rangeStepP [], const int epochsP = 0) { if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; //---------------------------------------------------------------------------- return true; } //——————————————————————————————————————————————————————————————————————————————
Moving 方法实现了 BOA 算法的主要步骤,并控制智能体(球)在解空间中的移动。首先,检查 if (!revision) 条件以确定该方法是否是首次被调用。如果 revision=false,则需要初始化智能体的位置。为此,会对定义为 popSize 的所有智能体执行循环,在其中对定义每个智能体决策参数的坐标执行嵌套循环。
在生成初始位置的阶段,会在给定范围内为每个智能体坐标选择一个随机值,u.SeInDiSp() 函数会结合步长(step)将该值调整为一个可接受的值。智能体的初始位置存储在 a[p].cB[c] 中,作为球的最佳个体解(在第一次迭代时,初始解等同于已知的最优解),在设置 revision=true 后,方法终止,以防止重新初始化数值。
在第二次及后续迭代中,启动循环以移动所有智能体。在更新坐标期间,会对所有智能体及其坐标执行嵌套循环,其中随机选择一个可用的最佳球袋来更新智能体的当前位置。位置的更新是基于先前位置,再加上基于所选球袋位置的随机变化量。u.RNDprobab() 函数返回 [0.0; 1.0] 范围内的随机数以添加随机噪声,而 u.RNDintInRange(1, 2) 函数则将随机值 1 或 2 与智能体的位置相乘。
更新位置后,会对其进行调整,结合最小值、最大值以及变化步长,将更新后的数值调整到指定范围内。
//—————————————————————————————————————————————————————————————————————————————— //--- The main step of the algorithm void C_AO_BOA::Moving () { //---------------------------------------------------------------------------- // Initial initialization if (!revision) { for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); a [p].cB [c] = a [p].c [c]; // Save the initial position } } revision = true; return; } //---------------------------------------------------------------------------- for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { int pocketID = u.RNDminusOne (numPockets); a [p].c [c] = a [p].cB [c] + u.RNDprobab () * (a [pocketID].cB [c] - u.RNDintInRange (1, 2) * a [p].cB [c]); a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————Revision 方法负责更新 BOA 算法中的最佳全局解,同时更新各球的最佳个体解。在方法结束时,球会根据其最佳个体解进行排序。
//—————————————————————————————————————————————————————————————————————————————— //--- Update the best solution taking into account greedy selection and the probability of making worse decisions void C_AO_BOA::Revision () { int bestIND = -1; for (int i = 0; i < popSize; i++) { if (a [i].f > fB) { fB = a [i].f; bestIND = i; } if (a [i].f > a [i].fB) { a [i].fB = a [i].f; ArrayCopy (a [i].cB, a [i].c, 0, 0, WHOLE_ARRAY); } } if (bestIND != -1) ArrayCopy (cB, a [bestIND].c, 0, 0, WHOLE_ARRAY); S_AO_Agent aT []; ArrayResize (aT, popSize); u.Sorting_fB (a, aT, popSize); } //——————————————————————————————————————————————————————————————————————————————
测试结果
现在让我们看看BOA算法的表现:=============================
5 Hilly's; Func runs: 10000; result: 0.63960620766331
25 Hilly's; Func runs: 10000; result: 0.3277725645995603
500 Hilly's; Func runs: 10000; result: 0.2514878043770147
=============================
5 Forest's; Func runs: 10000; result: 0.3885662762060409
25 Forest's; Func runs: 10000; result: 0.1955657530616877
500 Forest's; Func runs: 10000; result: 0.15336230733273673
=============================
5 Megacity's; Func runs: 10000; result: 0.5415384615384615
25 Megacity's; Func runs: 10000; result: 0.19046153846153846
500 Megacity's; Func runs: 10000; result: 0.10530769230769324
=============================
总得分: 2.79367 (31.04%)
如你所见,该算法的性能相当弱,未能进入我们的排名表,因此我决定深入研究该算法,并提出了一些关于如何使其有效运作的想法。让我们再次看一下球的移动方程:
X_new = X + rnd [0.0; 1.0] × (P - I × X)
在该方程中,比率 I 被应用于球的当前坐标值,这具有不明确的物理含义,因为实际上缩放是应用于坐标的绝对值。更自然的做法是将该比率提取出来,以便允许针对球袋和球的坐标值之间的差值进行缩放。然后,得到的公式描述了一种真正的物理意义,即球要么无法到达球袋,要么会飞越它。变化性由 [0.0, 1.0] 范围内随机数的额外噪声因子提供。
因此,我们得到了球的移动方程:
X_new = X + rnd [0.0; 1.0] × (P -X) × I
所以,下面是 Moving () 方法修改版本的完整代码,其中显示了被注释掉的作者的方程,之后是我的版本。
//—————————————————————————————————————————————————————————————————————————————— //--- The main step of the algorithm void C_AO_BOA::Moving () { //---------------------------------------------------------------------------- // Initial initialization if (!revision) { for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); a [p].cB [c] = a [p].c [c]; // Save the initial position as the best individual solution } } revision = true; return; } //---------------------------------------------------------------------------- for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { int pocketID = u.RNDminusOne (numPockets); //a [p].c [c] = a [p].cB [c] + u.RNDprobab () * (a [pocketID].cB [c] - u.RNDintInRange (1, 2) * a [p].cB [c]); a [p].c [c] = a [p].cB [c] + u.RNDprobab () * (a [pocketID].cB [c] - a [p].cB [c]) * u.RNDintInRange (1, 2); a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————
现在,经过修改后,让我们看看算法在使用原版本表现最佳的参数时,其结果如何:
BOA|Billiards Optimization Algorithm|50.0|8.0|
=============================
5 Hilly's; Func runs: 10000; result: 0.8727603657603271
25 Hilly's; Func runs: 10000; result: 0.7117647027521633
500 Hilly's; Func runs: 10000; result: 0.25339119302510993
=============================
5 Forest's;函数运行次数:10000;结果:0.9893902762645717
25 Forest's; Func runs: 10000; result: 0.7601448268715335
500 Forest's; Func runs: 10000; result: 0.3498925749480034
=============================
5 Megacity's; Func runs: 10000; result: 0.6184615384615385
25 Megacity's; Func runs: 10000; result: 0.45876923076923076
500 Megacity's; Func runs: 10000; result: 0.14586153846153965
=============================
总得分:5.09389 (56.60%)
在进行了几次更多的实验后,我找到了能产生更好结果的参数:
BOA|Billiards Optimization Algorithm|50.0|25.0|
=============================
5 Hilly's; Func runs: 10000; result: 0.957565927297626
25 Hilly's; Func runs: 10000; result: 0.8259872884790693
500 Hilly's; Func runs: 10000; result: 0.2523458952211869
=============================
5 Forest's; Func runs: 10000; result: 0.9999999999999929
25 Forest's; Func runs: 10000; result: 0.900362056289584
500 Forest's; Func runs: 10000; result: 0.305018130407844
=============================
5 Megacity's; Func runs: 10000; result: 0.7353846153846153
25 Megacity's; Func runs: 10000; result: 0.5252307692307692
500 Megacity's; Func runs: 10000; result: 0.09563076923077005
=============================
总得分:5.59753 (62.19%)
让我们看一下 BOA 算法在测试函数上运行的可视化结果。在搜索空间中未观察到特定的特征行为;“球”的移动显得混乱无序。尤其值得注意的是,该算法能成功处理中小维度的难题,然而,在大维度问题上表现出收敛困难。在平滑的 Hilly 函数上这一点尤为明显,其表现甚至比离散的 Megacity 函数还要差,与其他基于种群的算法相比,这是一种极其罕见的现象。还值得注意的是,该算法在解决小维度问题时容易陷入局部最小值。

BOA在 Hilly 测试函数上

BOA on the Forest test function

BOA在 Megacity 测试函数上
让我们总结下测试结果并观察算法效率。尽管存在严重的缺陷,该算法还是表现出了相当高的效率,在最佳优化算法排名中占据了第 8 位。
| # | 算法 | 说明 | Hilly | Hilly 最终结果 | Forest | Forest 最终结果 | Megacity (离散) | Megacity 最终结果 | 最终结果 | 最大 % | ||||||
| 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | ||||||||
| 1 | ANS | 交叉邻近搜索 | 0.94948 | 0.84776 | 0.43857 | 2.23581 | 1.00000 | 0.92334 | 0.39988 | 2.32323 | 0.70923 | 0.63477 | 0.23091 | 1.57491 | 6.134 | 68.15 |
| 2 | CLA | 代码锁定算法(JOO) | 0.95345 | 0.87107 | 0.37590 | 2.20042 | 0.98942 | 0.91709 | 0.31642 | 2.22294 | 0.79692 | 0.69385 | 0.19303 | 1.68380 | 6.107 | 67.86 |
| 3 | AMOm | 动物迁徙优化M | 0.90358 | 0.84317 | 0.46284 | 2.20959 | 0.99001 | 0.92436 | 0.46598 | 2.38034 | 0.56769 | 0.59132 | 0.23773 | 1.39675 | 5.987 | 66.52 |
| 4 | (P+O)ES | (P+O) 进化策略 | 0.92256 | 0.88101 | 0.40021 | 2.20379 | 0.97750 | 0.87490 | 0.31945 | 2.17185 | 0.67385 | 0.62985 | 0.18634 | 1.49003 | 5.866 | 65.17 |
| 5 | CTA | 彗尾算法(JOO) | 0.95346 | 0.86319 | 0.27770 | 2.09435 | 0.99794 | 0.85740 | 0.33949 | 2.19484 | 0.88769 | 0.56431 | 0.10512 | 1.55712 | 5.846 | 64.96 |
| 6 | TETA | 时间演化旅行算法(JOO) | 0.91362 | 0.82349 | 0.31990 | 2.05701 | 0.97096 | 0.89532 | 0.29324 | 2.15952 | 0.73462 | 0.68569 | 0.16021 | 1.58052 | 5.797 | 64.41 |
| 7 | SDSm | 随机扩散搜索 M | 0.93066 | 0.85445 | 0.39476 | 2.17988 | 0.99983 | 0.89244 | 0.19619 | 2.08846 | 0.72333 | 0.61100 | 0.10670 | 1.44103 | 5.709 | 63.44 |
| 8 | BOAm | 台球优化算法 M | 0.95757 | 0.82599 | 0.25235 | 2.03590 | 1.00000 | 0.90036 | 0.30502 | 2.20538 | 0.73538 | 0.52523 | 0.09563 | 1.35625 | 5.598 | 62.19 |
| 9 | AAm | 射箭算法 M | 0.91744 | 0.70876 | 0.42160 | 2.04780 | 0.92527 | 0.75802 | 0.35328 | 2.03657 | 0.67385 | 0.55200 | 0.23738 | 1.46323 | 5.548 | 61.64 |
| 10 | ESG | 社会群体的进化(JOO) | 0.99906 | 0.79654 | 0.35056 | 2.14616 | 1.00000 | 0.82863 | 0.13102 | 1.95965 | 0.82333 | 0.55300 | 0.04725 | 1.42358 | 5.529 | 61.44 |
| 11 | SIA | 模拟各向同性退火(JOO) | 0.95784 | 0.84264 | 0.41465 | 2.21513 | 0.98239 | 0.79586 | 0.20507 | 1.98332 | 0.68667 | 0.49300 | 0.09053 | 1.27020 | 5.469 | 60.76 |
| 12 | ACS | 人工协同搜索 | 0.75547 | 0.74744 | 0.30407 | 1.80698 | 1.00000 | 0.88861 | 0.22413 | 2.11274 | 0.69077 | 0.48185 | 0.13322 | 1.30583 | 5.226 | 58.06 |
| 13 | DA | 辩证算法 | 0.86183 | 0.70033 | 0.33724 | 1.89940 | 0.98163 | 0.72772 | 0.28718 | 1.99653 | 0.70308 | 0.45292 | 0.16367 | 1.31967 | 5.216 | 57.95 |
| 14 | BHAm | 黑洞算法 M | 0.75236 | 0.76675 | 0.34583 | 1.86493 | 0.93593 | 0.80152 | 0.27177 | 2.00923 | 0.65077 | 0.51646 | 0.15472 | 1.32195 | 5.196 | 57.73 |
| 15 | ASO | 无政府社会优化 | 0.84872 | 0.74646 | 0.31465 | 1.90983 | 0.96148 | 0.79150 | 0.23803 | 1.99101 | 0.57077 | 0.54062 | 0.16614 | 1.27752 | 5.178 | 57.54 |
| 16 | RFO | 皇家同花顺优化算法 (JOO) | 0.83361 | 0.73742 | 0.34629 | 1.91733 | 0.89424 | 0.73824 | 0.24098 | 1.87346 | 0.63154 | 0.50292 | 0.16421 | 1.29867 | 5.089 | 56.55 |
| 17 | AOSm | 原子环路搜索 M | 0.80232 | 0.70449 | 0.31021 | 1.81702 | 0.85660 | 0.69451 | 0.21996 | 1.77107 | 0.74615 | 0.52862 | 0.14358 | 1.41835 | 5.006 | 55.63 |
| 18 | TSEA | 龟壳进化算法(JOO) | 0.96798 | 0.64480 | 0.29672 | 1.90949 | 0.99449 | 0.61981 | 0.22708 | 1.84139 | 0.69077 | 0.42646 | 0.13598 | 1.25322 | 5.004 | 55.60 |
| 19 | DE | 差分进化 | 0.95044 | 0.61674 | 0.30308 | 1.87026 | 0.95317 | 0.78896 | 0.16652 | 1.90865 | 0.78667 | 0.36033 | 0.02953 | 1.17653 | 4.955 | 55.06 |
| 20 | CRO | 化学反应优化 | 0.94629 | 0.66112 | 0.29853 | 1.90593 | 0.87906 | 0.58422 | 0.21146 | 1.67473 | 0.75846 | 0.42646 | 0.12686 | 1.31178 | 4.892 | 54.36 |
| 21 | BIO | 血缘遗传优化算法 (JOO) | 0.81568 | 0.65336 | 0.30877 | 1.77781 | 0.89937 | 0.65319 | 0.21760 | 1.77016 | 0.67846 | 0.47631 | 0.13902 | 1.29378 | 4.842 | 53.80 |
| 22 | BSA | 鸟群算法 | 0.89306 | 0.64900 | 0.26250 | 1.80455 | 0.92420 | 0.71121 | 0.24939 | 1.88479 | 0.69385 | 0.32615 | 0.10012 | 1.12012 | 4.809 | 53.44 |
| 23 | HS | 和声搜索算法 | 0.86509 | 0.68782 | 0.32527 | 1.87818 | 0.99999 | 0.68002 | 0.09590 | 1.77592 | 0.62000 | 0.42267 | 0.05458 | 1.09725 | 4.751 | 52.79 |
| 24 | SSG | 树苗播种和生长算法 | 0.77839 | 0.64925 | 0.39543 | 1.82308 | 0.85973 | 0.62467 | 0.17429 | 1.65869 | 0.64667 | 0.44133 | 0.10598 | 1.19398 | 4.676 | 51.95 |
| 25 | BCOm | 细菌趋化优化算法M | 0.75953 | 0.62268 | 0.31483 | 1.69704 | 0.89378 | 0.61339 | 0.22542 | 1.73259 | 0.65385 | 0.42092 | 0.14435 | 1.21912 | 4.649 | 51.65 |
| 26 | ABO | 非洲水牛优化 | 0.83337 | 0.62247 | 0.29964 | 1.75548 | 0.92170 | 0.58618 | 0.19723 | 1.70511 | 0.61000 | 0.43154 | 0.13225 | 1.17378 | 4.634 | 51.49 |
| 27 | (PO)ES | (PO) 进化策略 | 0.79025 | 0.62647 | 0.42935 | 1.84606 | 0.87616 | 0.60943 | 0.19591 | 1.68151 | 0.59000 | 0.37933 | 0.11322 | 1.08255 | 4.610 | 51.22 |
| 28 | TSm | 禁忌搜索优化算法 | 0.87795 | 0.61431 | 0.29104 | 1.78330 | 0.92885 | 0.51844 | 0.19054 | 1.63783 | 0.61077 | 0.38215 | 0.12157 | 1.11449 | 4.536 | 50.40 |
| 29 | BSO | 头脑风暴优化 | 0.93736 | 0.57616 | 0.29688 | 1.81041 | 0.93131 | 0.55866 | 0.23537 | 1.72534 | 0.55231 | 0.29077 | 0.11914 | 0.96222 | 4.498 | 49.98 |
| 30 | WOAm | 鲸鱼优化算法M | 0.84521 | 0.56298 | 0.26263 | 1.67081 | 0.93100 | 0.52278 | 0.16365 | 1.61743 | 0.66308 | 0.41138 | 0.11357 | 1.18803 | 4.476 | 49.74 |
| 31 | AEFA | 人工电场算法 | 0.87700 | 0.61753 | 0.25235 | 1.74688 | 0.92729 | 0.72698 | 0.18064 | 1.83490 | 0.66615 | 0.11631 | 0.09508 | 0.87754 | 4.459 | 49.55 |
| 32 | AEO | 基于人工生态系统的优化算法 | 0.91380 | 0.46713 | 0.26470 | 1.64563 | 0.90223 | 0.43705 | 0.21400 | 1.55327 | 0.66154 | 0.30800 | 0.28563 | 1.25517 | 4.454 | 49.49 |
| 33 | ACOm | 蚁群优化 M | 0.88190 | 0.66127 | 0.30377 | 1.84693 | 0.85873 | 0.58680 | 0.15051 | 1.59604 | 0.59667 | 0.37333 | 0.02472 | 0.99472 | 4.438 | 49.31 |
| 34 | BFO-GA | 细菌觅食优化 - ga | 0.89150 | 0.55111 | 0.31529 | 1.75790 | 0.96982 | 0.39612 | 0.06305 | 1.42899 | 0.72667 | 0.27500 | 0.03525 | 1.03692 | 4.224 | 46.93 |
| 35 | SOA | 简单优化算法 | 0.91520 | 0.46976 | 0.27089 | 1.65585 | 0.89675 | 0.37401 | 0.16984 | 1.44060 | 0.69538 | 0.28031 | 0.10852 | 1.08422 | 4.181 | 46.45 |
| 36 | ABHA | 人工蜂巢算法 | 0.84131 | 0.54227 | 0.26304 | 1.64663 | 0.87858 | 0.47779 | 0.17181 | 1.52818 | 0.50923 | 0.33877 | 0.10397 | 0.95197 | 4.127 | 45.85 |
| 37 | ACMO | 大气云层模型优化 | 0.90321 | 0.48546 | 0.30403 | 1.69270 | 0.80268 | 0.37857 | 0.19178 | 1.37303 | 0.62308 | 0.24400 | 0.10795 | 0.97503 | 4.041 | 44.90 |
| 38 | ADAMm | 自适应动量评估 M | 0.88635 | 0.44766 | 0.26613 | 1.60014 | 0.84497 | 0.38493 | 0.16889 | 1.39880 | 0.66154 | 0.27046 | 0.10594 | 1.03794 | 4.037 | 44.85 |
| 39 | CGO | 混沌博弈优化算法 | 0.57256 | 0.37158 | 0.32018 | 1.26432 | 0.61176 | 0.61931 | 0.62161 | 1.85267 | 0.37538 | 0.21923 | 0.19028 | 0.78490 | 3.902 | 43.35 |
| 40 | ATAm | 人工部落算法 M | 0.71771 | 0.55304 | 0.25235 | 1.52310 | 0.82491 | 0.55904 | 0.20473 | 1.58867 | 0.44000 | 0.18615 | 0.09411 | 0.72026 | 3.832 | 42.58 |
| 41 | ASHA | 人工淋浴算法 | 0.89686 | 0.40433 | 0.25617 | 1.55737 | 0.80360 | 0.35526 | 0.19160 | 1.35046 | 0.47692 | 0.18123 | 0.09774 | 0.75589 | 3.664 | 40.71 |
| 42 | ASBO | 适应性社会行为优化 | 0.76331 | 0.49253 | 0.32619 | 1.58202 | 0.79546 | 0.40035 | 0.26097 | 1.45677 | 0.26462 | 0.17169 | 0.18200 | 0.61831 | 3.657 | 40.63 |
| 43 | MEC | 思维进化计算 | 0.69533 | 0.53376 | 0.32661 | 1.55569 | 0.72464 | 0.33036 | 0.07198 | 1.12698 | 0.52500 | 0.22000 | 0.04198 | 0.78698 | 3.470 | 38.55 |
| 44 | CSA | 圆搜索算法 | 0.66560 | 0.45317 | 0.29126 | 1.41003 | 0.68797 | 0.41397 | 0.20525 | 1.30719 | 0.37538 | 0.23631 | 0.10646 | 0.71815 | 3.435 | 38.17 |
| 45 | IWO | 入侵性杂草优化 | 0.72679 | 0.52256 | 0.33123 | 1.58058 | 0.70756 | 0.33955 | 0.07484 | 1.12196 | 0.42333 | 0.23067 | 0.04617 | 0.70017 | 3.403 | 37.81 |
| RW | 随机游走 | 0.48754 | 0.32159 | 0.25781 | 1.06694 | 0.37554 | 0.21944 | 0.15877 | 0.75375 | 0.27969 | 0.14917 | 0.09847 | 0.52734 | 2.348 | 26.09 | |
总结
改进后的台球优化算法 (BOAm) 在测试函数上展现了有趣的结果。对所提供数据的分析表明,该算法在中小型问题上取得了最佳结果,在迭代达到 10,000 次时,在 Hilly (0.957)、Forest (0.999) 和 Megacity (0.735) 测试中获得了最高分。这证明了其在解决中等复杂度问题时寻找最优解的高效性。然而,随着问题规模的增加,性能显著下降,这在 1000 个变量的场景结果中显而易见,其得分分别降至 0.252、0.305 和 0.095。
尤其值得注意的是,该算法改进版本的性能有了显著提升,达到了最大可能结果的 62.19%,是原始版本 31.04% 的两倍。这种令人印象深刻的改进仅通过修改一行代码实现,而这行代码涉及球位置的更新方程。
算法的简洁性既是其优势也是其局限——它直观、易于实现,且基于优雅的台球概念——但可能需要额外的修改才能高效处理高维问题。总体而言,在排名表中位列前十的 BOAm 代表了一种有前景的元启发式方法,它在解空间的探索与开发之间取得了良好的平衡。

图例 2. 根据相应测试结果的算法颜色分级

图例 3. 算法测试结果直方图(比例从 0 到 100,越高越好,其中 100 是最大可能的理论结果,存档中有一个用于计算评级表的脚本)
BOA算法的优缺点:
优点:
- 外部参数非常少。
- 实现简单。
- 在中小型问题上表现良好。
- 在具有“陡峭”极值(如 Forest 函数)的问题上结果优异。
缺点:
- 在低维问题上会陷入局部极值。
- 在高维“平滑”问题(如 Hilly 函数)上的收敛速度和准确率非常低。
本文附带了一个文档,其中包含了算法代码的当前版本。文章作者不对典型算法描述的绝对准确性负责。对其中进行了多处修改,从而提升搜索能力。文章中表述的结论和论断是基于实验的结果。
文中所用程序
| # | 名称 | 类型 | 说明 |
|---|---|---|---|
| 1 | #C_AO.mqh | 库 | 种群算法的父类 算法 |
| 2 | #C_AO_enum.mqh | 库 | 群体优化算法枚举 |
| 3 | TestFunctions.mqh | 库 | 测试函数函数库 |
| 4 | TestStandFunctions.mqh | 库 | 测试台函数库 |
| 5 | Utilities.mqh | 库 | 辅助函数库 |
| 6 | CalculationTestResults.mqh | 库 | 用于计算对比表中结果的脚本 |
| 7 | Testing AOs.mq5 | 脚本 | 所有种群优化算法的统一测试平台 |
| 8 | Simple use of population optimization algorithms.mq5 | 脚本 | 一个不包含可视化功能的种群优化算法使用示例 |
| 9 | Test_AO_BOAm.mq5 | 脚本 | BOAm test stand |
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/17325
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。
从新手到专家:使用 MQL5 制作动画新闻标题(一)
MQL5 简介(第 17 部分):构建趋势反转 EA 交易
交易中的神经网络:基于 ResNeXt 模型的多任务学习(终篇)