
种群优化算法:社群进化(ESG)
内容
1. 概述
在优化领域,有范围广阔的种群算法,旨在寻找各种问题中的最优解。然而,尽管它们很重要,但多种群和多群体算法在我以前的文章中并未得到充分的涵盖。有鉴于此,我觉得有必要针对这个迷人而有前景的话题进行更详细的研究。
多种群算法基于多个独立种群来求解优化问题的思路。种群在逻辑上并行运作,可以交流有关最优解的信息,这样就令同时探索参数空间的不同区域并、并找到不同的最优值成为可能。另一方面,多群体算法使用许多互动份子的社群(群落),其也可以彼此合作,并交流达成最佳解的信息。
在本文中,我们将研究本文专门创建的多种群 ESG 算法。我们将研究该类算法的基本原理。此外,我们将研究比较研究的结果,这将令我们能够评估这些算法相比单种群优化方法的有效性。
2. 算法
多种群算法可以基于以下原理进行各种组合:
1. 社群。该算法并非针对单份子运作,而是那些通过合作和经验交流而联合的社群。每个群都有自己的决策中枢,以及当作优化个体的份子集合。群间互动、分享经验,并用相关最优解的信息来改善它们的结果。
2. 集体运动。社群内份子在参数空间中交互,并一起移动。这允许群体探索参数空间的不同区域,并分享有关寻找最优解的信息。
3. 局部和全局经验。每个社群都存储有关其中最优解(本地经验)的信息。在所有群(全局经验)中还有一个总体最佳分数。群体保留最佳解,分享经验,并用它们来改进结果。
4. 进化和经验交流。该算法会经历迭代,在此期间,社群会更新和分享经验。这是改进解的迭代,并寻求最优结果。
5. 自适性和多样性。通过互动和经验交流,群体可以自适应不断变化的条件,并寻找到各种最优解。该算法具有自适属性,令其能够有效地响应优化问题不断变化的条件和要求。群体可以自适新的条件,改变它们在参数空间中移动的策略,并基于经验更新它们的决策。这允许算法有效地搜索最优解,尤其是在问题条件随时间变化的情况下。
上面我们谈论了多种群算法的基本原理。现在我们来看看 ESG 搜索策略的特性。
假设我们有一个份子社会,我们称之为 “社群”。在这个群体中,某个行为模型(“中枢”)占主导地位,且该群体的份子追随这个模型,但有一定的偏差,其可用一定的分布律来描述。大多数份子略微偏离中枢,但在群体的影响区域内有些偏差很大,其边界由分布决定。当份子中出现更自适的行为形态时,它将成为群体的新中枢。因此,该群转向寻找份子行为的最稳定模型。
可以有若干个这样的群体,而且它们是独立的,所以可以称为多种群算法,在低层次上模拟社群中个体成员的行为,且在高层次上模拟群体的普遍行为。
鉴于这个概念,这样的状况很可能会出现在一些单独的群、甚或所有群同时停止它们的拓展,并陷入局部极值之时。为免遭此景,我们引入了“扩展社群的影响方圆”的概念。如果每次迭代毫无寸进,则扩展群边界,从而允许开拓新的搜索区域,并令种群及群体多样化。如果该群找到一个优于前值的解,则群边界半径将再次缩减到默认最小值。这有助于算法免于陷入局部陷阱,并在必要时强化对新区域的探索。增加半径也有助于社群的多样性。不同的群将探索参数空间的不同区域。
这种用于社群进化的多种群算法的概念看起来很有前途。然而,并非一切都像初看那么简单。该群中枢的当前位置也许在相应的坐标上处于不幸的位置,甚至扩大影响区域也未必有效。在这种情况下,我们可以说发生了 “对角线扩展” (就像在 ACO 算法中,蚂蚁只沿着它们的路径奔跑,不会跑偏),而实际上需要 “直角扩展”,或者确实也可能出现相反的状况。
若要克服上述问题,重点是确保在群之间转移成功的经验。为此目的,可以允许一些份子从“盟友”群的中枢借用一些思路。因此,中枢行为形态将影响其它群的单个份子。顺便说一句,影响不可能、也没必要是积极的。社群的行为模型如图例 1 所示制程。
图例 1. 算法操作。分离群,在缺乏进展的情况下扩展,在改善解的情况下收窄,
按 “p0” 份子(份子位于群索引 0 处)从相邻的 “Bt”(最佳团队)群中借用 “最佳思路”(坐/标)
ESG 算法的伪代码可以如下表示:
- 在搜索空间中随机放置群的中枢。
- 将群的份子围绕给定分布 * 的相应中心放置。
- 计算份子的适应度值。
- 更新全局解。
- 更新每个群的中枢。
- 如果中枢的位置并未改善,则扩大群边界,如果我们设法改善了位置,则减小群边界。
- 将群的份子围绕给定分布的相应中心放置。
- 将来自“盟友群”中枢的信息添加到每个群的一个份子中(份子从随机选择的盟友群中接收一组坐标)。
- 计算份子的适应度值。
- 从步骤 4 开始重复,直到满足停止准则。
* — 在 ESG 中,我使用分布幂律来表示群份子相对于中枢的分布。不过,也可用其它分布律,包括它们的策略独立部分逻辑的组合。该主题是开放的,可供试验。
我们转到代码回顾。为了描述一个社群,我们将编写 S_Group 结构,其中包含几个成员变量:
- “cB” - 存储 “center” 坐标的值数组。
- “fB” - 以 “-DBL_MAX” 初始化的中枢适应度函数。
- “sSize” - 群大小。
- “sRadius” - 群半径。
结构中的 Init 方法取两个参数:“coords” - 坐标的数量,和 “groupSize” - 群的大小。
//—————————————————————————————————————————————————————————————————————————————— struct S_Group { void Init (int coords, int groupSize) { ArrayResize (cB, coords); fB = -DBL_MAX; sSize = groupSize; } double cB []; double fB; int sSize; double sRadius; }; //——————————————————————————————————————————————————————————————————————————————
所述搜索个体的简单结构也适用于 ESG 算法的逻辑。我决定在群描述字段中不包含个体份子的结构。每个群在访问其份子时都作为普通种群的一部分,这将允许保持从算法外部对个体的常规访问,同时避免不必要地复制群份子到个体。
S_Agent 结构的定义包含两个变量:
- “c” - 个体坐标值的数组。
- “f” - 以 “-DBL_MAX” 初始化的个体适应度值。
Init 方法取 “coords” 参数来调整 “c” 数组的大小。
//—————————————————————————————————————————————————————————————————————————————— struct S_Agent { void Init (const int coords) { ArrayResize (c, coords); f = -DBL_MAX; } double c []; //coordinates double f; //fitness }; //——————————————————————————————————————————————————————————————————————————————
定义 C_AO_ESG 类,其中包含多个字段和方法:
1. 公开字段:
- “cB” - 全局解的最佳坐标值数组。
- “fB” — 最佳坐标的适应度值。
- “a” - 表示个体的 S_Agent 类型对象数组。
- “rangeMax” — 搜索数组范围的最大值。
- "rangeMin" — 搜索数组范围的最小值。
- “rangeStep” - 搜索数组的步长值。
2. 方法:
- “Init” - 初始化类成员变量的函数。接受参数:坐标数量、种群规模、群数量、初始群半径、群扩展因子、和分布度。
- “Moving” - 该方法负责个体的移动。
- “Revision” - 该方法负责个体的修订。
- “SeInDiSp” - 按给定步长计算范围内数值的方法。
- “RNDfromCI” - 按给定间生成随机数的方法。
- “Scale” - 将数值从一个范围缩放到另一个范围的方法。
- “PowerDistribution” - 根据幂律分布生成数值的方法。
3. 私密字段:
- “coords” - 坐标的数量。
- “popSize” - 种群规模。
- “gr” - 表示群的 S_Group 类型对象数组。
- “groups” - 群数量。
- “groupRadius” - 群半径。
- “expansionRatio” - 扩展比率。
- “power” - 幂。
- “revision” - 指示需要修订的标志。
//—————————————————————————————————————————————————————————————————————————————— class C_AO_ESG { //---------------------------------------------------------------------------- public: double cB []; //best coordinates public: double fB; //FF of the best coordinates public: S_Agent a []; //agents public: double rangeMax []; //maximum search range public: double rangeMin []; //manimum search range public: double rangeStep []; //step search public: void Init (const int coordinatesNumberP, //coordinates number const int populationSizeP, //population size const int groupsP, //number of groups const double groupRadiusP, //group radius const double expansionRatioP, //expansion ratio const double powerP); //power public: void Moving (); public: void Revision (); //---------------------------------------------------------------------------- private: int coords; private: int popSize; //population size private: S_Group gr []; //group private: int groups; //number of groups private: double groupRadius; //group radius private: double expansionRatio; //expansion ratio private: double power; //power private: bool revision; 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: double PowerDistribution (const double In, const double outMin, const double outMax, const double power); }; //——————————————————————————————————————————————————————————————————————————————
类的 Init 方法基于所传递参数初始化类变量。除了变量的主要初始化和设置数组的大小之外,如果群数量不是种群规模的倍数,该方法还会计算每个群中的份子数量。
“partInSwarms” 数组的大小调整为 “groups”,其中 “groups” 是群的数量。然后,将变量 “particles” 设置为将 “popSize” 除以 “groups” 的结果,其中 “popSize” 是种群规模。“partInSwarms” 数组以数值 “particles” 填充,即没有余数的量。然后,通过从 “popSize” 中减去 “particles” 和 “groups” 的乘积来计算丢失元素的数量。如果有丢失的元素(“lost > 0”),那么在 'while' 循环中它们会在群中均匀分布。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_ESG::Init (const int coordinatesNumberP, //coordinates number const int populationSizeP, //population size const int groupsP, //number of groups const double groupRadiusP, //group radius const double expansionRatioP, //expansion ratio const double powerP) { MathSrand ((int)GetMicrosecondCount ()); // reset of the generator fB = -DBL_MAX; revision = false; coords = coordinatesNumberP; popSize = populationSizeP; groups = groupsP; groupRadius = groupRadiusP; expansionRatio = expansionRatioP; power = powerP; //---------------------------------------------------------------------------- int partInSwarms []; ArrayResize (partInSwarms, groups); int particles = popSize / groups; ArrayInitialize (partInSwarms, particles); int lost = popSize - particles * groups; if (lost > 0) { int pos = 0; while (true) { partInSwarms [pos]++; lost--; pos++; if (pos >= groups) pos = 0; if (lost == 0) break; } } //---------------------------------------------------------------------------- ArrayResize (rangeMax, coords); ArrayResize (rangeMin, coords); ArrayResize (rangeStep, coords); ArrayResize (cB, coords); ArrayResize (gr, groups); for (int s = 0; s < groups; s++) gr [s].Init (coords, partInSwarms [s]); ArrayResize (a, popSize); for (int i = 0; i < popSize; i++) a [i].Init (coords); } //——————————————————————————————————————————————————————————————————————————————
Moving 方法用于在优化开始时生成群的中枢和个体。该方法执行以下操作:
- 在外部 “for” 循环中为每个 “s” 群生成中枢。为此,嵌套的 “for” 循环为每个 “c” 坐标在给定范围内生成一个 “coordinate” 随机值。然后将 “coordinate” 值转换为所需的范围,并存储在 “gr[s].cB[c]” 数组之中。
- 在外部 “for” 循环中为每个 “s” 群生成个体,以及逐个 “p” 个体。“radius” 的值是基于给定的参数,在嵌套的 “for” 循环中按群的当前状态计算得出。然后,通过调整相对于范围边界的 “radius” 来计算 “min” 和 “max” 值。然后调用 “PowerDistribution” 函数在给定范围内生成随机 “coordinate” 值。生成的 “coordinate” 值被转换并存储在 “a[cnt].c[c]” 数组之中。
- 将 “revision” 标志设置为 “true”,从而指示正在生成中枢和个体。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_ESG::Moving () { if (!revision) { int cnt = 0; double coordinate = 0.0; double radius = 0.0; double min = 0.0; double max = 0.0; //generate centers---------------------------------------------------------- for (int s = 0; s < groups; s++) { gr [s].sRadius = groupRadius; for (int c = 0; c < coords; c++) { coordinate = RNDfromCI (rangeMin [c], rangeMax [c]); gr [s].cB [c] = SeInDiSp (coordinate, rangeMin [c], rangeMax [c], rangeStep [c]); } } //generate individuals of groups-------------------------------------------- for (int s = 0; s < groups; s++) { for (int p = 0; p < gr [s].sSize; p++) { for (int c = 0; c < coords; c++) { radius = (rangeMax [c] - rangeMin [c]) * gr [s].sRadius; min = gr [s].cB [c] - radius; max = gr [s].cB [c] + radius; if (min < rangeMin [c]) min = rangeMin [c]; if (max > rangeMax [c]) max = rangeMax [c]; coordinate = PowerDistribution (gr [s].cB [c], min, max, power); a [cnt].c [c] = SeInDiSp (coordinate, rangeMin [c], rangeMax [c], rangeStep [c]); } cnt++; } } revision = true; } } //——————————————————————————————————————————————————————————————————————————————
生成新份子的主要动作发生在 “Revision” 方法中,其会更最佳全局解,生成新的群个体,并通过将信息从 “盟友 ”群的中枢转移到一个份子,完成在群之间交流经验。因此,一个群中只有一个份子被允许从其它群中借用经验。该方法执行以下操作:
- 更新全局解。在 “for” 循环中,遍历所有个体,并检查当前个体的适应度函数的值是否超过了当前最佳值。然后更新最佳值,并将当前个体的坐标数组复制到最佳解的坐标数组当中。
- 生成新的群个体。在 “for” 循环中,遍历所有群及其个体。半径以及每个群的最小和最大坐标值则在嵌套循环中计算。然后调用 “PowerDistribution” 函数生成随机坐标值,并将结果存储在个体坐标数组之中。
- 群之间的经验交流。在 “for” 循环中,遍历所有群。在嵌套的 “for” 循环中,会生成一个随机值,用于判定与哪个群交流经验。然后,取所选群的坐标值更新当前群中个体的坐标值。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_ESG::Revision () { //---------------------------------------------------------------------------- //update the best global solution for (int i = 0; i < popSize; i++) { if (a [i].f > fB) { fB = a [i].f; ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY); } } //---------------------------------------------------------------------------- int cnt = 0; bool impr = false; for (int s = 0; s < groups; s++) { impr = false; for (int p = 0; p < gr [s].sSize; p++) { if (a [cnt].f > gr [s].fB) { gr [s].fB = a [cnt].f; ArrayCopy (gr [s].cB, a [cnt].c, 0, 0, WHOLE_ARRAY); impr = true; } cnt++; } if (!impr) gr [s].sRadius *= expansionRatio; else gr [s].sRadius = groupRadius; if (gr [s].sRadius > 0.5) gr [s].sRadius = 0.5; } //generate individuals of groups---------------------------------------------- double coordinate = 0.0; double radius = 0.0; double min = 0.0; double max = 0.0; cnt = 0; for (int s = 0; s < groups; s++) { for (int p = 0; p < gr [s].sSize; p++) { for (int c = 0; c < coords; c++) { if (RNDfromCI (0.0, 1.0) < 1.0) { radius = (rangeMax [c] - rangeMin [c]) * gr [s].sRadius; min = gr [s].cB [c] - radius; max = gr [s].cB [c] + radius; if (min < rangeMin [c]) min = rangeMin [c]; if (max > rangeMax [c]) max = rangeMax [c]; coordinate = PowerDistribution (gr [s].cB [c], min, max, power); a [cnt].c [c] = SeInDiSp (coordinate, rangeMin [c], rangeMax [c], rangeStep [c]); } } cnt++; } } //exchange of experience---------------------------------------------------------------- cnt = 0; for (int s = 0; s < groups; s++) { for (int c = 0; c < coords; c++) { int posSw = (int)RNDfromCI (0, groups); if (posSw >= groups) posSw = groups - 1; //if (sw [posSw].fB > sw [s].fB) { a [cnt].c [c] = gr [posSw].cB [c]; } } cnt += gr [s].sSize; } } //——————————————————————————————————————————————————————————————————————————————
在编写了如上讲述的主要 ESG 算法之后,我决定进行更改,并允许不同群的份子交流信息,以便提高算法的组合品质。为此,我们必须对个体结构进行修改。我们需要额外的字段:“cMain” - 主坐标,和 “fMain” - 主经验。
//—————————————————————————————————————————————————————————————————————————————— struct S_Agent { void Init (const int coords) { ArrayResize (c, coords); ArrayResize (cMain, coords); f = -DBL_MAX; fMain = -DBL_MAX; } double c []; //coordinates double cMain []; //coordinates double f; //fitness double fMain; //fitness }; //——————————————————————————————————————————————————————————————————————————————
两个选项之间的区别在于针对 “Revision” 方法所做的修改:
1. 在主版本中,个体之间的经验交流是在群层面运作的。在内部 “for” 循环中,选择一个随机群,并将当前个体的坐标值替换为所选群中的中枢坐标值。因此,群在交换经验时,把经验转移到相应群中的唯一份子。
2. 在第二种个选项中,个体之间的经验交流是在整个种群的层面上运作的,此即,在群的份子之间,如果所选份子具有更高的适应性,则才会交流。因此,在群之间,只有最佳份子才能将经验传递给最差的份子。在内部 “for” 循环中,选择一个随机个体,并以一定的概率(由 “copyProb” 值确定),将当前个体的坐标值替换为群中所选个体的坐标值。
此外,第二个选项还有一个额外的代码模块,用于更新个体。如果当前个体的适应度函数值大于其先前的最佳值(f > fMain),则当前个体的坐标值将更新为其当前最佳解(cMain)的值。这允许个体保存并在以后使用它们的最佳决策。
//—————————————————————————————————————————————————————————————————————————————— void C_AO_ESG::Revision () { //---------------------------------------------------------------------------- //Update the best global solution for (int i = 0; i < popSize; i++) { if (a [i].f > fB) { fB = a [i].f; ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY); } } //---------------------------------------------------------------------------- //update agents for (int p = 0; p < popSize; p++) { if (a [p].f > a [p].fMain) { a [p].fMain = a [p].f; ArrayCopy (a [p].cMain, a [p].c, 0, 0, WHOLE_ARRAY); } } //---------------------------------------------------------------------------- int cnt = 0; bool impr = false; for (int s = 0; s < groups; s++) { impr = false; for (int p = 0; p < gr [s].sSize; p++) { if (a [cnt].f > gr [s].fB) { gr [s].fB = a [cnt].f; ArrayCopy (gr [s].cB, a [cnt].c, 0, 0, WHOLE_ARRAY); impr = true; } cnt++; } if (!impr) gr [s].sRadius *= expansionRatio; else gr [s].sRadius = groupRadius; if (gr [s].sRadius > 0.5) gr [s].sRadius = 0.5; } //generate individuals of groups---------------------------------------------- double coordinate = 0.0; double radius = 0.0; double min = 0.0; double max = 0.0; cnt = 0; for (int s = 0; s < groups; s++) { for (int p = 0; p < gr [s].sSize; p++) { for (int c = 0; c < coords; c++) { if (RNDfromCI (0.0, 1.0) < 0.6) { radius = (rangeMax [c] - rangeMin [c]) * gr [s].sRadius; min = gr [s].cB [c] - radius; max = gr [s].cB [c] + radius; if (min < rangeMin [c]) min = rangeMin [c]; if (max > rangeMax [c]) max = rangeMax [c]; coordinate = PowerDistribution (gr [s].cB [c], min, max, power); a [cnt].c [c] = SeInDiSp (coordinate, rangeMin [c], rangeMax [c], rangeStep [c]); } } cnt++; } } //exchange of experience---------------------------------------------------------------- cnt = 0; for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { int pos = (int)RNDfromCI (0, popSize); if (pos >= popSize) pos = popSize - 1; if (RNDfromCI(0.0, 1.0) < copyProb) { if (a [pos].fMain > a [p].fMain) { a [p].c [c] = a [pos].cMain [c]; } } } } } //——————————————————————————————————————————————————————————————————————————————
作为算法第二版的实验和测试结果,总体结果并没有带来预期的进展,并且略有恶化。这可以通过以下事实来解释:重点是将份子的经验保持在它们自己的群的边界内,且不允许群之间彻底混合思路。应保留每个群的独特经验,并且只应确保部分经验交流。
实验的失败不是最终的,并不意味着算法的改进是不可能的。这只是一次尝试,让我们了解哪些方面值得关注,以及哪些策略最适合应用。通过进一步的研究和开发,获得的知识可用于创建算法的新变体,从而显著改进搜索能力。重要的是,在实现既定目标时,保持乐观和坚定。测试结果如下所示。
3. 测试结果
ESG 主要版本测试台结果:
C_AO_ESG|200|100|0.1|2.0|10.0
=============================
5 Hilly's; Func runs: 10000; result: 0.9990564816911227
25 Hilly's; Func runs: 10000; result: 0.7965424362150277
500 Hilly's; Func runs: 10000; result: 0.35055904999599663
=============================
5 Forest's; Func runs: 10000; result: 1.0
25 Forest's; Func runs: 10000; result: 0.8286255415345216
500 Forest's; Func runs: 10000; result: 0.13102081222227177
=============================
5 Megacity's; Func runs: 10000; result: 0.8233333333333333
25 Megacity's; Func runs: 10000; result: 0.5529999999999999
500 Megacity's; Func runs: 10000; result: 0.04724999999999998
=============================
All score: 5.52939 (61.44%)
略微修改的 ESG 版本测试台结果:
C_AO_MPSO|200|100|0.1|1.1|10.0|1.0
=============================
5 Hilly's; Func runs: 10000; result: 0.9986983861349696
25 Hilly's; Func runs: 10000; result: 0.7971379560351051
500 Hilly's; Func runs: 10000; result: 0.3351159723676586
=============================
5 Forest's; Func runs: 10000; result: 1.0
25 Forest's; Func runs: 10000; result: 0.8288612676775615
500 Forest's; Func runs: 10000; result: 0.11374411604788078
=============================
5 Megacity's; Func runs: 10000; result: 0.8333333333333333
25 Megacity's; Func runs: 10000; result: 0.5116666666666667
500 Megacity's; Func runs: 10000; result: 0.049316666666666654
=============================
All score: 5.46787 (60.75%)
我们可以看到算法的主要版本具有良好的收敛性。在测试函数 Hilly 和 Forest 上,在收敛图上可以看到轨迹中的轻微散射。不过,在 Megacity 函数上,这种分散相当大,尽管据此测试函数的大多数算法也显示出广泛的收敛散射。与早前表述的大多数算法不同,该算法“首选”更大种群规模 - 200(一般只用 50),尽管实际上局次数量成比例减少。ESG 在局部极值下工作良好。此属性受多种群算法 “本性” 的影响。
ESG 依据 Hilly 测试函数
ESG 依据 Forest 测试函数
ESG 依据 Megacity 测试函数
ESG 算法展现出不错的结果,在排位表中名列前茅。可以注意到,具有 10 个参数的 Forest 函数收敛为 100%,并且几乎完全收敛;具有 10 个参数的 Hilly 函数收敛为 99.9%。该表包含算法主版本的结果,而实验版本位于 “variant2” 文件夹当中。
# | AO | 说明 | 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 | BGA | 二进制遗传算法 | 0.99992 | 0.99484 | 0.50483 | 2.49959 | 1.00000 | 0.99975 | 0.32054 | 2.32029 | 0.90667 | 0.96400 | 0.23035 | 2.10102 | 6.921 | 76.90 |
2 | (P+O)ES | (P+O) 进化策略 | 0.99934 | 0.91895 | 0.56297 | 2.48127 | 1.00000 | 0.93522 | 0.39179 | 2.32701 | 0.83167 | 0.64433 | 0.21155 | 1.68755 | 6.496 | 72.18 |
3 | 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 |
4 | ESG | 社群进化 | 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 |
5 | SIA | 模拟各向同性退火 | 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 |
6 | 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 |
7 | 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 |
8 | 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 |
9 | (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 |
10 | 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 |
11 | 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 |
12 | 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 |
13 | 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 |
14 | Micro-AIS | 微人工免疫系统 | 0.79547 | 0.51922 | 0.30861 | 1.62330 | 0.72956 | 0.36879 | 0.09398 | 1.19233 | 0.37667 | 0.15867 | 0.02802 | 0.56335 | 3.379 | 37.54 |
15 | COAm | 布谷鸟优化算法 M | 0.75820 | 0.48652 | 0.31369 | 1.55841 | 0.74054 | 0.28051 | 0.05599 | 1.07704 | 0.50500 | 0.17467 | 0.03380 | 0.71347 | 3.349 | 37.21 |
16 | SDOm | 螺旋动力学优化 M | 0.74601 | 0.44623 | 0.29687 | 1.48912 | 0.70204 | 0.34678 | 0.10944 | 1.15826 | 0.42833 | 0.16767 | 0.03663 | 0.63263 | 3.280 | 36.44 |
17 | NMm | Nelder-Mead 方法 M | 0.73807 | 0.50598 | 0.31342 | 1.55747 | 0.63674 | 0.28302 | 0.08221 | 1.00197 | 0.44667 | 0.18667 | 0.04028 | 0.67362 | 3.233 | 35.92 |
18 | FAm | 萤火虫算法 M | 0.58634 | 0.47228 | 0.32276 | 1.38138 | 0.68467 | 0.37439 | 0.10908 | 1.16814 | 0.28667 | 0.16467 | 0.04722 | 0.49855 | 3.048 | 33.87 |
19 | GSA | 重力搜索算法 | 0.64757 | 0.49197 | 0.30062 | 1.44016 | 0.53962 | 0.36353 | 0.09945 | 1.00260 | 0.32667 | 0.12200 | 0.01917 | 0.46783 | 2.911 | 32.34 |
20 | BFO | 细菌觅食优化 | 0.61171 | 0.43270 | 0.31318 | 1.35759 | 0.54410 | 0.21511 | 0.05676 | 0.81597 | 0.42167 | 0.13800 | 0.03195 | 0.59162 | 2.765 | 30.72 |
21 | ABC | 人工蜂群 | 0.63377 | 0.42402 | 0.30892 | 1.36671 | 0.55103 | 0.21874 | 0.05623 | 0.82600 | 0.34000 | 0.14200 | 0.03102 | 0.51302 | 2.706 | 30.06 |
22 | BA | 蝙蝠算法 | 0.59761 | 0.45911 | 0.35242 | 1.40915 | 0.40321 | 0.19313 | 0.07175 | 0.66810 | 0.21000 | 0.10100 | 0.03517 | 0.34617 | 2.423 | 26.93 |
23 | SA | 模拟退火 | 0.55787 | 0.42177 | 0.31549 | 1.29513 | 0.34998 | 0.15259 | 0.05023 | 0.55280 | 0.31167 | 0.10033 | 0.02883 | 0.44083 | 2.289 | 25.43 |
24 | IWDm | 智能水滴 M | 0.54501 | 0.37897 | 0.30124 | 1.22522 | 0.46104 | 0.14704 | 0.04369 | 0.65177 | 0.25833 | 0.09700 | 0.02308 | 0.37842 | 2.255 | 25.06 |
25 | PSO | 粒子群优化 | 0.59726 | 0.36923 | 0.29928 | 1.26577 | 0.37237 | 0.16324 | 0.07010 | 0.60572 | 0.25667 | 0.08000 | 0.02157 | 0.35823 | 2.230 | 24.77 |
26 | MA | 猴子算法 | 0.59107 | 0.42681 | 0.31816 | 1.33604 | 0.31138 | 0.14069 | 0.06612 | 0.51819 | 0.22833 | 0.08567 | 0.02790 | 0.34190 | 2.196 | 24.40 |
27 | SFL | 蛙跳 | 0.53925 | 0.35816 | 0.29809 | 1.19551 | 0.37141 | 0.11427 | 0.04051 | 0.52618 | 0.27167 | 0.08667 | 0.02402 | 0.38235 | 2.104 | 23.38 |
28 | FSS | 鱼群搜索 | 0.55669 | 0.39992 | 0.31172 | 1.26833 | 0.31009 | 0.11889 | 0.04569 | 0.47467 | 0.21167 | 0.07633 | 0.02488 | 0.31288 | 2.056 | 22.84 |
29 | RND | 随机 | 0.52033 | 0.36068 | 0.30133 | 1.18234 | 0.31335 | 0.11787 | 0.04354 | 0.47476 | 0.25333 | 0.07933 | 0.02382 | 0.35648 | 2.014 | 22.37 |
30 | GWO | 灰狼优化器 | 0.59169 | 0.36561 | 0.29595 | 1.25326 | 0.24499 | 0.09047 | 0.03612 | 0.37158 | 0.27667 | 0.08567 | 0.02170 | 0.38403 | 2.009 | 22.32 |
31 | CSS | 收费系统搜索 | 0.44252 | 0.35454 | 0.35201 | 1.14907 | 0.24140 | 0.11345 | 0.06814 | 0.42299 | 0.18333 | 0.06300 | 0.02322 | 0.26955 | 1.842 | 20.46 |
32 | EM | 类电磁算法 | 0.46250 | 0.34594 | 0.32285 | 1.13129 | 0.21245 | 0.09783 | 0.10057 | 0.41085 | 0.15667 | 0.06033 | 0.02712 | 0.24412 | 1.786 | 19.85 |
总结
综上所述,社群进化算法是一种基于群体间合作和经验分享的有效优化方法。它具有适应性强、多样性、等特性,能够在各种优化问题中找到最优解。
我可以推荐 ESG 算法用于需要优化参数的各个领域。例如,它可用于优化机器学习中的超参数、优化最优控制问题中的函数、解决组合优化问题、以及需要查找最优参数值的其它问题。
所表述的算法可以视作一种模板,可以辅以之前文章中讲述的各种独立技术和搜索策略。此外,每个群都可用单独的优化算法,例如 PSO、ABC、ACO、等等。因此,ESG 算法的架构令实现该类优化方法,以及配合使用变得容易,分别结合了每种算法的优点。
需要强调的是,ESG 是一个独立的解决方案,效果很好,是解决复杂问题的一种极其灵活的方式。它的全部潜力可以通过实验和发展核心思想来释放,而这种实验的机会向所有人开放。
图例 2. 算法颜色渐变是根据相关测试,而大于或等于 0.99 的结果,会以白色高亮显示
图例 3. 算法测试结果的直方图(标尺从 0 到 100,越多越好,
其中 100 是理论上的最大可能结果(存档提供了一个计算排位表格的脚本)。
ESG 的优点和缺点:
优势:
- 简单架构。
- 高收敛性。
- 对计算资源要求不高。
缺点:
- 在具有大量参数的函数上结果不佳。
本文附有一个存档,其中包含前几篇文章中讲述的算法代码的当前更新版本。文章作者不对规范算法讲述的绝对准确性负责。它们当中进行了多处修改,从而提升搜索能力。文章中表述的结论和论断是基于实验的结果。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/14136



