种群优化算法:杜鹃优化算法(COA)
内容
1. 概述2. 算法描述、决策树和 Levy 飞行
3. COA 代码
4. 测试结果
1. 概述
杜鹃是一种迷人的鸟类,不仅因为它会唱歌,还因为它激进的繁殖策略,其中包括将蛋产入其它鸟类的巢穴之中。 因此,这种鸟完全将其应承担的父母责任转移到其它物种身上。 每种杜鹃都会产下某种颜色和大小的蛋,以便更好地匹配各种养父母的蛋。 扔进其它鸟巢的杜鹃雏鸟通常比鸟巢主人自己的雏鸟更大、更强壮,所以杜鹃需要更多的食物。 在发育过程中,霍奇森(Hodgson)的杜鹃雏鸟在翅膀上以开放喙的形式发展出一种特殊的图案,这令它们能够从养父母那里获得更多的食物。 杜鹃并不是唯一表现出这种特征的鸟类。 在至少 80 种鸟类中都发现了筑巢寄生。 此外,这种现象在某些种群的社会性昆虫中很普遍 — 大黄蜂、蜜蜂、和蚂蚁,它们的雌性渗透到另一个繁殖地,杀死原本的女王并产卵。 一些鱼类也存在巢穴寄生,例如来自非洲坦噶尼喀湖(Lake Tanganyika)的鲶鱼,它们将卵扔给其它在嘴里孵化鱼卵的鱼类。
杜鹃搜索是杨(Yang)和 Deb 于 2009 年开发的最新型自然启发式算法之一。 它基于一些杜鹃物种的寄生。 该算法已由所谓的 Levy 飞行进一步改进,远超简单的各向同性随机游走方法。
2. 算法说明
杜鹃优化算法(COA)用于连续非线性优化。 COA 的灵感来自这种鸟的生活方式。 优化算法基于物种产蛋繁殖的特点。 像其它进化方法一样,COA 从初始种群开始。 该算法的基础是争夺生存权。 在竞争生存的同时,一些鸟类会死亡。 幸存的杜鹃会搬到更好的地方,开始繁殖和产蛋。 最后,幸存的杜鹃会收敛这样的方式,如此杜鹃社会获得了相似的适应度。
这种方法的主要优点是它的简单性:杜鹃搜索只需要四个可理解的参数,因此调优变得不费吹灰之力。
在杜鹃搜索算法中,鸟巢中原来的蛋被解释为优化问题的可能解,杜鹃蛋代表新的解。 该方法的终极目标是使用这些新的(并且可能更好)寄生杜鹃蛋解决方案来取代当前的鸟巢蛋解。 这种替换,迭代进行,最终导出最佳解。
杨教授和 Deb 教授为该算法提出了以下三组理想状态:
1. 每只杜鹃产一枚蛋,并将其放入随机选择的鸟巢当中。
2. 拥有优质鸟蛋的最佳巢穴将传给下一代。
3. 可用的鸟巢数量是固定的,且鸟巢具有检测出外来鸟蛋的 “pa” 概率。 在这种情况下,宿主鸟可以扔掉鸟蛋,或离开巢穴,鸟蛋就会死亡。
出于简单起见,第三个假设可以用 n 个鸟巢的 pa 分数来近似。 对于最大化问题,解的品质或适当性也许只是与目标函数成正比。 然而,也可以定义适应度函数的其它(更复杂的)表达式。
对于每次迭代 g,随机选择一枚杜鹃鸟蛋 i,并采用 Levy 飞行生成新的解 xi(g + 1),这是一种随机游走,其中步数由具有一定概率分布的步长范围内判定,且步长的方向是各向同性和随机的。 根据该方法的原建者的说法,采用 Levy 飞行策略比其它简单的随机游走更可取,因为它会产生更好的整体性能。 一般的 Levy 飞行方程如下所示:
xi(g + 1) = xi(g) + α ⊕ levy(λ),
其中 g 表示当前生成的数量,而 α > 0 表示步长,这应该与正在研究的特定问题的规模有关。 ⊕ 符号则表示逐元素乘法。 请注意,这本质上是一个马尔可夫(Markov)链,因为第 g + 1 代的下一个位置仅取决于 g 代的当前位置,以及分别由第一项和第二项给出的转移概率。 该转移概率由 Levy 分布调制为:
levy(λ) ∼ g−λ, (1 < λ ≤ 3),
其具有无限均值的无限方差。 实践表明,在固定的 2.0 度下,可以达到最好的结果。 此处,这些步骤基本上形成了一个随机游走过程,具有幂律重尾步长分布。 从计算的角度来看,利用 Levy 飞行生成随机数包括两个阶段:首先,根据均匀分布选择随机方向,然后根据所选的 Levy 分布生成步骤。 然后,该算法评估新解的适用度,并将其与当前解进行比较。 如果新解提供了更好的适用度,则它将取代当前解。 另一方面,一些鸟巢被遗弃(鸟巢的宿主扔掉杜鹃蛋,或离开巢穴,故鸟蛋坏死了),以便提升针对搜索空间的探索,从而寻找更有希望的解。 替换率由 pa 概率判定,模型参数需要调整以便提高性能。 该算法应用迭代方式,直到满足停止条件。 常见的终止准则是,已找到满足较低阈值的解、已达到固定的更新换代数量、或者连续迭代不再产生更好的结果。
我们来更详细地讨论杜鹃产蛋的过程。 从所有鸟巢中,随机选择一个预备产蛋的鸟巢。 由于鸟蛋是一个解,因此可以用鸟蛋的质量来表示。 如果杜鹃蛋的质量高于宿主蛋,那么它将被替换。 否则,宿主蛋将留在鸟巢中。 事实上,随后的进化将自幸存的雏鸟继续。 这意味着,如果宿主蛋的雏鸟幸存下来,那么进化将从同一个地方继续。 进而只有当杜鹃蛋变得更强势,并且从新的地方继续寻找解时,才有可能进一步发展。 示意性决策树如图例 1 所示。
图例 1. 决策树。 红点是开始,绿点是最终决策
决策树之后算法基础的第二个组成部分是 Levy 飞行。 Levy 飞行是一种随机游走(马尔可夫统计过程),其中跳跃的长度以步为单位变化,跳跃的方向随机变化,概率分布是帕累托(Pareto)分布的特例,其特征是重尾。 它被定义为空间中的跳跃,并且跳跃在随机方向上是各向同性的。 Levy 飞行是描述异常随机过程的工具。 分散是无限的(长距跳跃也有可能),跳跃的长度在所有级别上都是自相似的(短跳穿插着长途飞行)。 术语 Levy 飞行有时会扩展为包括发生在离散网格,而不仅是连续空间中的随机游走。
如果我们考虑一个参数的优化问题,可以想象 Levy 飞行在布谷鸟算法中的明确应用。 我们以一个假设的函数(图例 2 中的黑线)为例,它在其大部分定义域,即水平线(y=x)上不会改变。 仅在很小的区域内,该函数会发生变化,并且有一个最大值。 如果我们从图例 2 中的橙点开始搜索最大值,然后得到一个带有 Levy 分布的随机值 x,我们将远离起点,同时在函数里不再得到变化。 然而,随着在分布尾部的强烈跳跃,我们得到一个绿点,这是一个比原始橙色更好的解,然后只从绿点我们能改善结果,同时接近函数的最大值。 在此示例中,Levy 飞行极大地提高了算法的搜索能力。
图例 2. 利用 Levy 飞行查找假设一维函数解的示例
Levy 飞行的概念用于混沌理论,用于模拟随机或伪随机自然现象(例如,信天翁的飞行,结合长短轨迹)。 示例包括地震数据分析、金融数学、密码学、信号分析、湍流运动,以及天文学、生物学和物理学中的许多应用。
COA 算法伪代码(图例 3):
1. 初始杜鹃是随机值。
2. 定义适应度。
3. 在随机鸟巢中产蛋。
4. 以给定的概率清空鸟巢。
5. 从当前位置将杜鹃发送到 Levi 飞行距离内的随机方向。
6. 定义适应度。
7. 在随机鸟巢中产蛋。
8. 以给定的概率清空鸟巢。
9. 重复 第 5 步,直到满足停止准则。
图例 3. COA 算法框图
3. COA 代码
我们开始研究算法的代码。 解是杜鹃,也是鸟蛋。 这是一个简单的结构,包括搜索空间中的坐标和适应度函数的值(鸟蛋质量)。
//—————————————————————————————————————————————————————————————————————————————— struct S_Cuckoo { double c []; //coordinates (egg parameters) double e; //egg quality }; //——————————————————————————————————————————————————————————————————————————————
我们以结构的形式讲述鸟巢。 此处,就像在鸟蛋的结构中一样,空间中有坐标和适应度函数的值。 “在鸟巢中产蛋”本质上意味着将鸟蛋的结构复制到鸟巢的结构之中。 当采用 pa 概率参数时,当从 0.0 到 pa 的随机数落在 [0.0;1.0] 范围内,且 e 值设置为 -DBL_MAX 时,鸟蛋则会从鸟巢中抛出。
//—————————————————————————————————————————————————————————————————————————————— struct S_Nest { void Init (int coordinates) { ArrayResize (c, coordinates); e = -DBL_MAX; } double c []; //coordinates (egg parameters) double e; //egg quality }; //——————————————————————————————————————————————————————————————————————————————
算法类。 这里声明了公开的初始化方法、在用户程序中调用的两个主要方法,优化问题参数的值范围,以及执行服务函数的其它私密方法。
//—————————————————————————————————————————————————————————————————————————————— class C_AO_COA { //============================================================================ public: double rangeMax []; //maximum search range public: double rangeMin []; //manimum search range public: double rangeStep []; //step search public: S_Cuckoo cuckoos []; //all the cuckoos public: double cB []; //best coordinates (egg parameters) public: double eB; //best eggs quality public: void Init (const int coordinatesP, //number of opt. parameters const int cuckoosP, //number of cuckoos const int nestsP, //number of cuckoo nests const double koef_paP, //probability of detection of cuckoo eggs const double koef_alphaP); //step control value public: void CuckooFlight (); public: void LayEggs (); //============================================================================ private: double SeInDiSp (double In, double InMin, double InMax, double Step); private: double RNDfromCI (double Min, double Max); private: double Scale (double In, double InMIN, double InMAX, double OutMIN, double OutMAX, bool Revers); private: S_Nest nests []; //nests private: int cuckoosNumber; //number of cuckoos private: int nestsNumber; //number of cuckoo nests private: double koef_pa; //probability of detection of cuckoo eggs private: double koef_alpha; //step control value private: double v []; private: int coordinates; //coordinates number private: bool clutchEggs; //clutch of eggs }; //——————————————————————————————————————————————————————————————————————————————
Init() 公开方法。 在此,变量的值被重置,并给数组分配内存。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_COA::Init (const int coordinatesP, //number of opt. parameters const int cuckoosP, //number of cuckoos const int nestsP, //number of cuckoo nests const double koef_paP, //probability of detection of cuckoo eggs const double koef_alphaP) //step control value { MathSrand (GetTickCount ()); clutchEggs = false; eB = -DBL_MAX; coordinates = coordinatesP; cuckoosNumber = cuckoosP; nestsNumber = nestsP; koef_pa = koef_paP; koef_alpha = koef_alphaP; ArrayResize (nests, nestsNumber); for (int i = 0; i < nestsNumber; i++) { nests [i].Init (coordinates); } ArrayResize (rangeMax, coordinates); ArrayResize (rangeMin, coordinates); ArrayResize (rangeStep, coordinates); ArrayResize (cB, coordinates); ArrayResize (v, coordinates); ArrayResize (cuckoos, cuckoosNumber); for (int i = 0; i < cuckoosNumber; i++) { ArrayResize (cuckoos [i].c, coordinates); } } //——————————————————————————————————————————————————————————————————————————————
第一个公开方法在每次“杜鹃飞行”迭代时都会调用。 如果 clutchEgg 标志关闭,那么我们将杜鹃发送到一个随机方向,在相应坐标范围内生成随机数。 如果启用该标志,则根据 Levy 飞行在 v 向量范围内的分布分派杜鹃的实际飞行。 v 向量是在 Init() 中针对每个坐标分别预先计算得出的,因为每个坐标可能具有不同的数值范围。
表达式 cuckoos [i].c [c] = cuckoos [i].c [c] + r1 * v [c] * pow (r2, -2.0);意即我们要加上 offset r1 * v [c] * pow (r2, -2.0),其中 r1 是 -1 或 1,它决定了偏移从原始位置的方向,V 是位移向量,R2 是从 0.0 到 20.0 范围内提高到 -2.0 的随机数。 将随机数升幂是 Levy 飞行函数。 其图形如图例 2 所示。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_COA::CuckooFlight () { //---------------------------------------------------------------------------- if (!clutchEggs) { for (int i = 0; i < coordinates; i++) v [i] = (rangeMax [i] - rangeMin [i]) * koef_alpha; for (int i = 0; i < cuckoosNumber; i++) { for (int c = 0; c < coordinates; c++) { cuckoos [i].c [c] = RNDfromCI (rangeMin [c], rangeMax [c]); cuckoos [i].c [c] = SeInDiSp (cuckoos [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } clutchEggs = true; } else { double r1 = 0.0; double r2 = 0.0; for (int i = 0; i < cuckoosNumber; i++) { for (int c = 0; c < coordinates; c++) { r1 = RNDfromCI (0.0, 1.0); r1 = r1 > 0.5 ? 1.0 : -1.0; r2 = RNDfromCI (1.0, 20.0); cuckoos [i].c [c] = cuckoos [i].c [c] + r1 * v [c] * pow (r2, -2.0); cuckoos [i].c [c] = SeInDiSp (cuckoos [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } } //——————————————————————————————————————————————————————————————————————————————
每次迭代调用的第二个公开方法是“产蛋”。 在这个方法中,通过算法再现了在鸟巢中产下杜鹃蛋的模拟。 这是通过从所有现有鸟巢中随机选择一个巢穴而实现的。 之后,将杜鹃蛋的质量与已经在鸟巢中的宿主鸟蛋的质量进行比较。 如果杜鹃蛋更好,则进行替换。 该方法算法的一个有趣特征是,即使杜鹃蛋更合适,产蛋后也会检查鸟蛋是否会死亡的概率。 这意味着任何鸟蛋都可能死亡 koef_pa,无论蛋下在哪里,就像在自然界中一样。 如果鸟蛋死亡或被扔出鸟巢,这实际上是一回事,那么鸟巢则允许产下任何新的健康鸟蛋,甚至降低一点,算法会探索新的地方。
这就是自然进化的途径之一,诸如鸟巢寄生,可以用几行代码来描述。 许多作者在他们的出版物中建议,鸟蛋被剔除后,取新的随机值重新初始化鸟巢,而这意味着从头开始搜索。 在大多数情况下,在提高算法的探索能力方面,这样做不会得到预期的结果。 我自己的研究表明,简单地让鸟巢空置更方便,其中一只杜鹃会在里面产蛋,且不管鸟蛋的质量如何。 这比随机值要好。 在研究时,可变性是通过从当前坐标往随机方向随机跳跃提供的。 结果就是,在寻找最佳解时,我们需要更少的迭代,从而提高算法的整体收敛率。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_COA::LayEggs () { int ind = 0; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ for (int i = 0; i < cuckoosNumber; i++) { ind = (int)round (RNDfromCI (0.0, nestsNumber - 1)); if (cuckoos [i].e > nests [ind].e) { nests [ind].e = cuckoos [i].e; ArrayCopy (nests [ind].c, cuckoos [i].c, 0, 0, WHOLE_ARRAY); if (cuckoos [i].e > eB) { eB = cuckoos [i].e; ArrayCopy (cB, cuckoos [i].c, 0, 0, WHOLE_ARRAY); } } else { ArrayCopy (cuckoos [i].c, nests [ind].c, 0, 0, WHOLE_ARRAY); } } //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv for (int n = 0; n < nestsNumber; n++) { if (RNDfromCI (0.0, 1.0) < koef_pa) { nests [ind].e = -DBL_MAX; } } } //——————————————————————————————————————————————————————————————————————————————
4. 测试结果
此为测试结果:
2022.11.30 11:31:54.490 Test_AO_COA_fast (EURUSD,M1) =============================
2022.11.30 11:31:54.507 Test_AO_COA_fast (EURUSD,M1) 1 Skin's; Func runs 10000 result: 4.918379100238852
2022.11.30 11:31:54.507 Test_AO_COA_fast (EURUSD,M1) Score: 1.00000
2022.11.30 11:31:54.854 Test_AO_COA_fast (EURUSD,M1) 20 Skin's; Func runs 10000 result: 4.257477577760983
2022.11.30 11:31:54.854 Test_AO_COA_fast (EURUSD,M1) Score: 0.84220
2022.11.30 11:32:02.346 Test_AO_COA_fast (EURUSD,M1) 500 Skin's; Func runs 10000 result: 1.3521208312080903
2022.11.30 11:32:02.346 Test_AO_COA_fast (EURUSD,M1) Score: 0.14849
2022.11.30 11:32:02.346 Test_AO_COA_fast (EURUSD,M1) =============================
2022.11.30 11:32:02.368 Test_AO_COA_fast (EURUSD,M1) 1 Forest's; Func runs 10000 result: 1.7600394018343262
2022.11.30 11:32:02.368 Test_AO_COA_fast (EURUSD,M1) Score: 0.99557
2022.11.30 11:32:02.775 Test_AO_COA_fast (EURUSD,M1) 20 Forest's; Func runs 10000 result: 0.4968964923017033
2022.11.30 11:32:02.775 Test_AO_COA_fast (EURUSD,M1) Score: 0.28107
2022.11.30 11:32:13.125 Test_AO_COA_fast (EURUSD,M1) 500 Forest's; Func runs 10000 result: 0.07638950254648778
2022.11.30 11:32:13.125 Test_AO_COA_fast (EURUSD,M1) Score: 0.04321
2022.11.30 11:32:13.125 Test_AO_COA_fast (EURUSD,M1) =============================
2022.11.30 11:32:13.148 Test_AO_COA_fast (EURUSD,M1) 1 Megacity's; Func runs 10000 result: 12.0
2022.11.30 11:32:13.148 Test_AO_COA_fast (EURUSD,M1) Score: 1.00000
2022.11.30 11:32:13.584 Test_AO_COA_fast (EURUSD,M1) 20 Megacity's; Func runs 10000 result: 2.69
2022.11.30 11:32:13.584 Test_AO_COA_fast (EURUSD,M1) Score: 0.22417
2022.11.30 11:32:24.379 Test_AO_COA_fast (EURUSD,M1) 500 Megacity's; Func runs 10000 result: 0.40800000000000003
2022.11.30 11:32:24.379 Test_AO_COA_fast (EURUSD,M1) Score: 0.03400
2022.11.30 11:32:24.379 Test_AO_COA_fast (EURUSD,M1) =============================
2022.11.30 11:32:24.379 Test_AO_COA_fast (EURUSD,M1) All score for C_AO_COA: 0.507633670637353
Levy 飞行杜鹃搜索算法显示出令人印象深刻的结果。 在大多数测试中,它的性能优于其它优化算法。 特别是,该算法在具有两个变量的平滑 Skin 函数,和具有两个变量的离散 Megacity 函数上显示出 100% 收敛。 更令人惊讶的是,它在离散函数上表现出优异的可扩展性。 在其它测试中,它仅略逊于蚁群算法。 目前,它在我们的评级表上是一个毫无疑问的领先者。
我想澄清一下,所有算法都有优调参数,这些参数会在某种程度上影响最终结果,因此这些算法中很可能具有更优化的参数,如此会令评级表看起来不同。 我只是展示了测试结果,以及我可以找到的参数,以确保获得最佳结果。 如果您设法找到了更多最佳参数,并获得更好的结果,那么我可以根据它们修正评级表。 有一种假设是,蚂蚁算法可以成功地与当前的领先者竞争,因为在某些指标上它领先于杜鹃鸟搜索算法,且在最终指标方面仅落后于它。 GWO 仍然是具有 1000 个变量的 Skin 函数的领先者。 无论如何,那些考虑解决优化问题时在项目中选取算法的人,可以浏览表格,并选择满足其特定需求的算法。
Skin 测试函数上的 COA。
Forest 测试函数上的 COA。
Megacity 测试函数上的 COA。
在测试台的可视化中,算法的行为与之前研究的行有所为不同,但有一些特征是将任务分解为研究区域的算法的特征,例如蜂群算法。 这表征了算法不专注于单个极值的能力,而是探索几个潜在的有前途的领域,为算法提供防止陷入局部极值的阻力。 有关于此,可以通过对鸟巢进行分类,并由杜鹃鸟根据鸟巢质量按比例选择来改进算法。 这意味着杜鹃会选择鸟巢,而不是像算法的常规版本那样,将鸟蛋放入随机选择的鸟巢当中。 然而,这并没有改善展现随机选择鸟巢的现实结果。 也许这与自然界中发生的事情相呼应。 在更聪明的宿主情况下更换鸟蛋更加困难,故导致随机和统计不合理。
该算法的另一个特点是它的行为类似于对多变量函数的随机游走。 从视觉上,它看起来像白噪声或旧电视屏幕。 只有在迭代结束时,局部极值位置的坐标集中度才很明显。 我更愿意提供更清晰的参数“晶化”,就像蚁群算法一样。 故此,我们遇到了所有优化算法的常见问题,它没有通用的解。 许多经典和新颖算法的作者都试图解决这个问题。
问题的本质如下:不确定所研究函数的哪个优化参数具有优先级或强度,不知道每个参数在多大程度上,以及如何影响结果。 例如,有若干参数,算法已经找到了正确的参数,但究竟是哪个起决定作用则是未知的。 该算法将继续尝试更改所有这些,尽管仅更改几个就足以达到全局极值。 当涉及到具有数以万计,和数千个变量的函数时,问题会加剧。 变量越多,问题就越严重。 从视觉上,这看起来像屏幕上的白噪声。
我已尝试至少部分解决这个问题。 如果事先不知道所研究函数的哪些参数应该改变,哪些应该保持不变,我们可以尝试以概率方式解决这个问题。 我们假设只需要更改所有参数的一部分,而不是同时更改所有参数。 PSO 算法的行为方式具有特征性。 随着优化函数的参数的增加,它的行为就像没有集中能力的云朵。 为此,我为算法引入了一个新参数,该参数设置坐标更改的概率,否则坐标将保持不变。
结果是... 有效!!! 测试结果有所改善。 我想要达成的“晶化”出现在多变量函数上。
测试台结果如下所示:
2022.12.03 16:01:26.256 Test_AO_COAm (EURUSD,M1) =============================
2022.12.03 16:01:27.511 Test_AO_COAm (EURUSD,M1) 1 Skin's; Func runs 10000 result: 4.918367945334852
2022.12.03 16:01:27.511 Test_AO_COAm (EURUSD,M1) Score: 1.00000
2022.12.03 16:01:30.291 Test_AO_COAm (EURUSD,M1) 20 Skin's; Func runs 10000 result: 4.328327964103814
2022.12.03 16:01:30.291 Test_AO_COAm (EURUSD,M1) Score: 0.85911
2022.12.03 16:01:59.306 Test_AO_COAm (EURUSD,M1) 500 Skin's; Func runs 10000 result: 1.3297901702583084
2022.12.03 16:01:59.306 Test_AO_COAm (EURUSD,M1) Score: 0.14316
2022.12.03 16:01:59.306 Test_AO_COAm (EURUSD,M1) =============================
2022.12.03 16:02:00.511 Test_AO_COAm (EURUSD,M1) 1 Forest's; Func runs 10000 result: 1.755200932219688
2022.12.03 16:02:00.511 Test_AO_COAm (EURUSD,M1) Score: 0.99283
2022.12.03 16:02:03.566 Test_AO_COAm (EURUSD,M1) 20 Forest's; Func runs 10000 result: 0.5089243656052672
2022.12.03 16:02:03.566 Test_AO_COAm (EURUSD,M1) Score: 0.28787
2022.12.03 16:02:35.468 Test_AO_COAm (EURUSD,M1) 500 Forest's; Func runs 10000 result: 0.08044934398920801
2022.12.03 16:02:35.468 Test_AO_COAm (EURUSD,M1) Score: 0.04551
2022.12.03 16:02:35.468 Test_AO_COAm (EURUSD,M1) =============================
2022.12.03 16:02:36.628 Test_AO_COAm (EURUSD,M1) 1 Megacity's; Func runs 10000 result: 12.0
2022.12.03 16:02:36.628 Test_AO_COAm (EURUSD,M1) Score: 1.00000
2022.12.03 16:02:39.628 Test_AO_COAm (EURUSD,M1) 20 Megacity's; Func runs 10000 result: 2.9899999999999998
2022.12.03 16:02:39.628 Test_AO_COAm (EURUSD,M1) Score: 0.24917
2022.12.03 16:03:11.892 Test_AO_COAm (EURUSD,M1) 500 Megacity's; Func runs 10000 result: 0.4244
2022.12.03 16:03:11.892 Test_AO_COAm (EURUSD,M1) Score: 0.03537
2022.12.03 16:03:11.892 Test_AO_COAm (EURUSD,M1) =============================
2022.12.03 16:03:11.892 Test_AO_COAm (EURUSD,M1) All score for C_AO_COAm: 0.5125572342985216
我们能在可视化中清楚地看到“晶化”。 起初看起来像白噪声的屏幕被清除,坐标开始集中,集中中心变得移动:
Megacity 测试函数上的 COAm。 “晶化”的效果更加明显。
一方面,存在可变性,即动态搜索新区域的能力;而另一方面,已达到的极端坐标的澄清能力。 下面是带有明显“晶化”的蚁群算法动画,以便进行比较:
Forest 测试函数上的 ACOm。
测试结果
算法 | 说明 | Skin | Forest | Megacity (离散) | 最终结果 | ||||||
2 参数 (1 F) | 40 参数 (20 F) | 1000 参数 (500 F) | 2 参数 (1 F) | 40 参数 (20 F) | 1000 参数 (500 F) | 2 参数 (1 F) | 40 参数 (20 F) | 1000 参数 (500 F) | |||
杜鹃优化算法 | 1.00000 | 0.85911 | 0.14316 | 0.99283 | 0.28787 | 0.04551 | 1.00000 | 0.24917 | 0.03537 | 0.51255778 | |
蚁群优化 | 0.98229 | 0.79108 | 0.12602 | 1.00000 | 0.62077 | 0.11521 | 0.38333 | 0.44000 | 0.02377 | 0.49805222 | |
人工蜂群 M | 1.00000 | 0.63922 | 0.08076 | 0.99908 | 0.20112 | 0.03785 | 1.00000 | 0.16333 | 0.02823 | 0.46106556 | |
人工蜂群 | 0.99339 | 0.73381 | 0.11118 | 0.99934 | 0.21437 | 0.04215 | 0.85000 | 0.16833 | 0.03130 | 0.46043000 | |
灰狼优化器 | 0.99900 | 0.48033 | 0.18924 | 0.83844 | 0.08755 | 0.02555 | 1.00000 | 0.10000 | 0.02187 | 0.41577556 | |
粒子群优化 | 0.99627 | 0.38080 | 0.05089 | 0.93772 | 0.14540 | 0.04856 | 1.00000 | 0.09333 | 0.02233 | 0.40836667 | |
随机 | 0.99932 | 0.44276 | 0.06827 | 0.83126 | 0.11524 | 0.03048 | 0.83333 | 0.09000 | 0.02403 | 0.38163222 |
杜鹃鸟搜索算法的一个优点是它的全局搜索采用飞行或 Levy 过程,而非标准的随机游走。 由于 Levy 飞行具有无限均值和方差,因此 COA 可以比标准高斯过程算法更有效地探索搜索空间。 Levy 飞行:一种随机游走过程,其特征是从具有幂律尾部的概率密度函数中选择的一系列瞬时跳跃。
目前,该算法在单个测试中明显优于其它算法,并且在其它“学科”中也不遑多让。 具有 1000 个参数的 Megacity 离散函数具有出色的结果,这令杜鹃鸟搜索成为交易者任务的绝佳工具(在大多数情况下是离散的)。 具有 1000 个参数的 Skin 函数的优秀(但不是最佳)结果,令我们有理由断言该算法特别适合训练神经网络和一般机器学习。
优点:
1. 高速。
2. 多功能性。 该算法适用于各种优化问题。 3. 不光死盯局部极值的能力。
4. 平滑和离散函数的高度收敛性。
5. 可扩展。
缺点:
1. 多种设置。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/11786