English Русский Español Deutsch 日本語 Português
preview
大逃杀优化器(BRO)

大逃杀优化器(BRO)

MetaTrader 5测试者 |
33 1
Andrey Dik
Andrey Dik

内容

  1. 引言
  2. 算法实现
  3. 测试结果


引言

在元启发式优化算法领域,各类算法的设计灵感通常源于自然过程、物理现象与进化机制,而如今一类全新的灵感来源应运而生 —— 电子游戏。大逃杀优化器(BRO) 由泰马兹・拉赫卡尔・法尔希(Taymaz Rahkar Farshi)提出,是一种创新型优化算法,其核心思想借鉴了《绝地求生》(PUBG)等热门大逃杀游戏的玩法机制。

BRO算法开创了优化方法中的一个全新门类 —— “基于游戏的优化算法”,进一步完善了现有的三大类优化算法体系,即:进化算法、群体智能算法,以及基于物理现象的算法,这些算法均属于广义上的基于种群的优化算法。在群体智能算法中,智能体之间相互协作以实现共同目标;与之不同,BRO算法中个体之间相互竞争,力求在搜索空间中生存下来并占据最优位置。

BRO算法的一大核心特点,是其独有的解竞争机制与“伤害”机制。每个解都会与其最近邻的解进行对比,失败者会受到“伤害”,而优胜者则清零伤害值。累积伤害过高的解会被移出种群,并由新的随机解替代,这一过程就如同PUBG中玩家受到致命伤害后被淘汰出局一样。从而为搜索空间探索引入新的搜索机会。


算法实现

可以将BRO算法形象地理解为一个虚拟世界:众多玩家降落在战场,最终只能有一人存活。这正是该类游戏的核心机制。现在,我们将这一理念引入优化问题的求解中。

在算法初始阶段,我们会生成一个解的种群,并将其随机分布在搜索空间内。每个解都是一名独特的“玩家”,拥有对应的位置和该位置的优劣程度(适应度)。随后进入核心竞争循环:每个解都会与其最近邻解进行比较,如同玩家在战场中相互对决。

当两个解“相遇”时,会根据其优劣展开比拼。更优解被判为胜利者,受到0点伤害;较差解被判为失败者,受到1点伤害。此伤害计数器是本算法的核心特征。失败解不仅会承受伤害,还会向种群中当前的最优解方向移动,尝试改善自身位置。这一移动模拟了玩家为求生存而寻找更安全、更有利位置的行为。

如果某个解累积的伤害过高(超出设定阈值),它就会被“淘汰出局” —— 从种群中移除,并由新的随机解替代。这就如同大逃杀游戏中玩家被淘汰后,下一局会有新玩家加入一样。该机制确保了种群的持续更新,并维持了解的多样性。

算法会周期性收缩搜索空间,类似于大逃杀中不断缩小的安全区,迫使玩家相互靠近。搜索边界会以当前找到的最优解为中心收缩,驱使种群向更有潜力的区域集中。

借助此方法,BRO算法实现了全局探索与局部开发之间的平衡。失败解向优秀解靠拢,保证整体优化趋势;彻底淘汰的解被新解替换,为搜索空间带来新的探索视角。与此同时,边界的周期性收缩,会强化对优质区域的局部精细搜索。

BRO算法

图例1. 运行中的BRO算法

上图展示了大逃杀优化器(BRO)算法的主要构成部分。搜索空间以一个二维区域呈现,图中的等高线象征待优化的目标函数(亮度越高的区域代表解的质量越好)。全局最优解以红色五角星标记,位于最高 “山峰” 的中心位置。优胜解用绿色圆点表示 —— 这类解伤害值为0(在与邻域解的对抗中获胜)。落败解用黄色(1点伤害)和橙色(2点伤害)圆点表示。新随机解用蓝色圆点表示,在某个解累积过量伤害时生成。失败解会向最优解方向移动(图中以虚线箭头表示)。搜索空间的收缩过程则以橙色虚线框表示,框体以当前最优解为中心不断缩小。

算法的关键阶段包括:初始化、与邻域解对比、向更优解移动、收缩搜索空间。

    在BRO算法中,各个解相互竞争,失败者会受到 “伤害”。伤害值过高的解将被新的随机解替换。至此,已经清楚算法原理,我们可以开始编写伪代码。

    初始化:

    1. 创建规模为popSize的种群
    2. 对于每个解,设置伤害计数器初始值为0
    3. 设置maxDamage最大伤害阈值
    4. 确定迭代次数(epoch)
    5. 计算用于周期性收缩搜索空间的初始收缩系数δ

    基础算法:

    1. 创建并初始化种群:
      • 遍历种群中的每个解:
        • 在指定搜索空间内生成随机坐标
    2. 遍历每一次迭代:
      • 若发现更优解,则更新全局最优解
      • 在解之间开展 “对战”:
        • 遍历种群中的每个解:
          • 寻找最近邻解(距离最小的解)
          • 对比当前解与邻域解的优劣:
            • 如果当前解更优:
              • 重置当前解的伤害计数器
              • 增加邻域解的伤害计数器
              • 失败者(邻域解)向全局最优解移动
            • 否则:
              • 增加当前解的伤害计数器
              • 重置邻域解的伤害计数器
              • 失败者(当前解)向全局最优解移动
      • 处理伤害值过高的解:
        • 遍历种群中的每个解:
          • 如果伤害计数器大于等于最大伤害阈值:
            • 重置伤害计数器
            • 用新的随机解替换该解
      • 周期性收缩搜索空间:
        • 如果当前迭代轮次可以被δ整除:
          • 计算整个种群所有坐标的标准差
          • 以最优解为中心收缩搜索空间
          • 更新δ值
    3. 返回找到的最优解

    该算法使用以下公式:

    • 计算用于收缩搜索空间的初始δ值:δ = ⌊迭代总次数 /log₁₀(迭代总次数)⌋
    • 计算解之间的欧氏距离:距离 = √(∑(解1 [c] − 解2 [c])²)
    • 失败解向全局最优解移动:解 [i][c] = 解 [i][c] + 随机数 × (最优解 [c] − 解 [i][c])
    • 计算每个维度坐标的平均值:均值 [c] = (∑解 [i][c]) / 种群规模
    • 计算每个维度坐标的标准差:标准差 [c] = √(∑(解 [i][c] − 均值 [c])² / 种群规模)
    • 搜索空间收缩公式: 新下限 [c] = 最优解 [c] − 标准差 [c],新上限 [c] = 最优解 [c] + 标准差 [c]
    • 空间收缩后更新δ参数:δ = δ + ⌊δ / 2⌉

    作者提出的周期性收缩搜索空间公式:Δ(δ) = 最大迭代次数 /log₁₀(最大迭代次数)。图表如下:

    函数

    图例2. δ参数与迭代次数的关系

    公式δ = 迭代次数 / log₁₀(迭代次数)的曲线图在BRO算法运行中至关重要,因为它决定了搜索空间每隔多少次迭代进行一次收缩。由图可见,δ值随迭代次数增加而增大,但由于除以了对数项,其增长速度远慢于迭代次数本身。这种非线性关系带来了以下优势:在优化前期(迭代次数较少时),搜索空间收缩相对频繁,有助于算法快速聚焦到有潜力的区域;在优化后期(迭代次数较多时),收缩频率降低,使得算法能对已发现的优质区域进行更精细地搜索。

    在我的实验中,对于δ参数的计算公式进行了改进,采用了两次对数运算。该版本的表现效果更优。

    // Calculate the initial delta to narrow the search space
      delta = (int)MathFloor(epochs / MathLog(MathLog(epochs)));
    

    让我们继续讨论代码。我们将实现一个继承自基类C_AO的自定义类C_AO_BRO,这意味着它将继承C_AO类的所有公有成员与保护成员,并且可以重写其行为。该类将是基于大逃杀机制优化算法的具体实现。

    1. 公有类成员:

    • popSize —— 设置种群规模。
    • maxDamage —— 设置最大伤害阈值,即解在被淘汰前能够承受的 “受击” 次数。
    • SetParams() —— 参数设置方法,根据存储在params数组中的值更新popSize和maxDamage,支持在算法运行时动态修改参数。
    • Init() —— 算法的初始化方法。接收参数:
      • rangeMinP[] —— 各变量的搜索范围下限。
      • rangeMaxP[] —— 各变量的搜索范围上限。
      • rangeStepP[] —— 各变量的搜索步长。
      • epochsP — 算法迭代次数(轮次)。默认值为0。
    • Moving() —— 解在搜索空间中的移动或更新核心逻辑。
    • Revision() —— 解的比较与更新逻辑,在此评估每个解所承受的 “伤害值”。
    • maxDamage —— 存储最大伤害阈值的公有成员变量。

    2. 类私有字段:

    • δ —— 搜索空间的收缩间隔。用于在优化过程中自适应调整搜索步长。
    • damages[] —— 种群中每个解的累计“伤害”值。 
    • epoch —— 算法当前迭代轮次(次数)。
    • epochs —— 算法最大迭代轮次(次数)。

    3. 辅助方法:

    • FindNearestNeighbor() —— 为指定索引的解查找最近邻解。用于解之间的交互逻辑。
    • CalculateDistance() —— 计算两个指定索引解之间的距离。
    • CalculateStandardDeviations() — 计算种群所有解的标准差,用于评估种群多样性并自适应调整搜索参数。
    • ShrinkSearchSpace() —— 收缩搜索空间方法。这是让算法收敛到最优解的标准技术。

    整体设计理念:

    C_AO_BRO是实现大逃杀优化算法的类,该算法的核心思想可简要概括如下:

    1. 初始化 —— 在指定搜索空间内创建随机解种群。
    2. 评估 —— 使用目标函数(适应度函数)对每个解进行评分。
    3. 大逃杀对抗 —— 各个解相互 “竞争”(根据目标函数值进行比较)。
    4. 伤害 — 部分解根据对战结果承受 “伤害”。
    5. 淘汰机制 —— “伤害”值超过 maxDamage 的解将被移出种群。
    6. 再生/替换 —— 被淘汰的解由新的随机解替代。
    7. 收缩搜索空间 —— 收缩搜索空间,使算法聚焦于最优区域。
    8. 循环迭代 — 重复执行第2-7步,直至达到设定迭代次数。
    //——————————————————————————————————————————————————————————————————————————————
    class C_AO_BRO : public C_AO
    {
      public: //--------------------------------------------------------------------
      ~C_AO_BRO () { }
      C_AO_BRO ()
      {
        ao_name = "BRO";
        ao_desc = "Battle Royale Optimizer";
        ao_link = "https://www.mql5.com/en/articles/17688";
    
        popSize   = 100;    // population size
        maxDamage = 3;      // maximum damage threshold
    
        ArrayResize (params, 2);
    
        params [0].name = "popSize";   params [0].val = popSize;
        params [1].name = "maxDamage"; params [1].val = maxDamage;
      }
    
      void SetParams ()
      {
        popSize   = (int)params [0].val;
        maxDamage = (int)params [1].val;
      }
    
      bool Init (constdouble &rangeMinP [],// minimum search range
                 const double &rangeMaxP [],  // maximum search range
                 const double &rangeStepP [], // search step
                 const int     epochsP = 0);  // number of epochs
    
      void Moving ();
      void Revision ();
    
      //----------------------------------------------------------------------------
      int maxDamage;    // maximum damage threshold
    
      private: //-------------------------------------------------------------------
      int    delta;      // interval for shrinking the search space
      int    damages []; // amount of damage for each solution
      int    epoch;      // current epoch
      int    epochs;     // maximum number of epochs
    
      // Auxiliary methods
      int    FindNearestNeighbor (int index);
      double CalculateDistance (int idx1, int idx2);
      void   CalculateStandardDeviations (double &sdValues []);
      void   ShrinkSearchSpace ();
    };
    //——————————————————————————————————————————————————————————————————————————————
    

    Init()方法用于初始化BRO算法,通过调用StandardInit(),根据传入的搜索范围和搜索步长执行标准初始化流程。如果StandardInit返回"false",则Init()方法也会返回"false",用于标记初始化错误。该方法会初始化"damages"数组:根据种群规模为各个解分配内存空间,并将每个解的初始伤害值设置为0。先设置总迭代次数"epochs",并将当前迭代计数"epoch"重置为 0。

    根据总迭代次数计算δ值,以实现搜索空间的逐步收缩。如果"δ"小于或等于0,则将其设置为1。总体而言,该方法通过初始化基础参数与数据结构,为算法运行做好准备。

    //——————————————————————————————————————————————————————————————————————————————
    bool C_AO_BRO::Init (const double &rangeMinP  [],  // minimum search range
                         const double &rangeMaxP  [],  // maximum search range
                         const double &rangeStepP [],  // search step
                         const int     epochsP = 0)    // number of epochs
    {
      if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
    
      //----------------------------------------------------------------------------
      // Initialize damage counters for each solution
      ArrayResize (damages, popSize);
      ArrayInitialize (damages, 0);
    
      // Set epochs
      epochs = epochsP;
      epoch  = 0;
    
      // Calculate the initial 'delta' to narrow the search space
      delta = (int)MathFloor (epochs / MathLog10 (epochs));
      if (delta <= 0) delta = 1;
    
      return true;
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    Moving()方法实现初始化解的种群逻辑:每个解的每一个坐标,都会在指定的最小值rangeMin和最大值rangeMax之间随机生成,并按照rangeStep进行离散化处理。该方法会确保种群仅被初始化一次。 

    /——————————————————————————————————————————————————————————————————————————————
    void C_AO_BRO::Moving ()
    {
      if (!revision)
      {
        // Initialize the population with random decisions
        for (int i = 0; i < popSize; i++)
        {
          for (int c = 0; c < coords; c++)
          {
            double coordinate = u.RNDfromCI (rangeMin [c], rangeMax [c]);
            a [i].c [c] = u.SeInDiSp (coordinate, rangeMin [c], rangeMax [c], rangeStep [c]);
          }
        }
    
        revision = true;
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    Revision()方法是BRO优化算法的核心步骤。该方法在每次迭代中都会更新最优解:如果当前种群中某个解优于当前全局最优解,则更新全局最优解。

    该方法会将解与其邻域解进行比较:对于每个解,在种群中找到其最近邻解,然后对比二者的适应度函数值。经对比后,较优解会获得 “奖励” —— 其伤害计数器被重置,而较差解的伤害计数器则加1。与此同时,该组中的较差解会向全局最优解方向移动。

    接下来,将执行受损解替换逻辑:如果某个解累积的“伤害”值达到上限(即达到maxDamage值),就会将其替换为一个随机生成的新解。算法会根据"δ"变量周期性收缩搜索范围。整个过程会在多次算法迭代中重复执行。通过与邻域解相互比较,各个解会逐步向更优的搜索区域移动。

    //——————————————————————————————————————————————————————————————————————————————
    void C_AO_BRO::Revision ()
    {
      epoch++;
    
      // Update the global best 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);
        }
      }
    
      // Compare each solution with its nearest neighbor and update damage counters
      for (int i = 0; i < popSize; i++)
      {
        int neighbor = FindNearestNeighbor (i);
    
        if (neighbor != -1)
        {
          if (a [i].f >= a [neighbor].f)
          {
            // Solution i wins
            damages [i] = 0;
            damages [neighbor]++;
    
            // The loser (neighbor) moves toward the best solution
            for (int c = 0; c < coords; c++)
            {
              double r = u.RNDfromCI (0, 1);
              a [neighbor].c [c] = a [neighbor].c [c] + r * (cB [c] - a [neighbor].c [c]);
              a [neighbor].c [c] = u.SeInDiSp (a [neighbor].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
            }
          }
          else
          {
            // Solution i loses
            damages [i]++;
            damages [neighbor] = 0;
    
            // The loser (i) moves to the best solution
            for (int c = 0; c < coords; c++)
            {
              double r = u.RNDfromCI (0, 1);
              a [i].c [c] = a [i].c [c] + r * (cB [c] - a [i].c [c]);
              a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
            }
          }
        }
      }
    
      // Check if any solution has reached maximum damage and replace it
      for (int i = 0; i < popSize; i++)
      {
        if (damages [i] >= maxDamage)
        {
          // Reset the damage counter
          damages [i] = 0;
    
          // Generate a new random solution
          for (int c = 0; c < coords; c++)
          {
            double coordinate = u.RNDfromCI (rangeMin [c], rangeMax [c]);
            a [i].c [c] = u.SeInDiSp (coordinate, rangeMin [c], rangeMax [c], rangeStep [c]);
          }
        }
      }
    
      // Periodic narrowing of the search space
      if (epochs > 0 && epoch % delta == 0)
      {
        ShrinkSearchSpace ();
        // Update delta
        delta = delta + (int)MathRound (delta / 2);
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    FindNearestNeighbor()方法用于查找种群中指定“索引”(index)对应解的最近邻索引。该方法遍历所有解,计算当前解与其他所有解的距离(排除自身索引),并返回距离最小的解的索引。如果无法找到最近邻(例如种群中仅有一个解),则返回-1。简言之,该方法的作用就是为指定解找到最近邻。

    //——————————————————————————————————————————————————————————————————————————————
    int C_AO_BRO::FindNearestNeighbor (int index)
    {
      double minDistance = DBL_MAX;
      int nearestIndex = -1;
    
      for (int i = 0; i < popSize; i++)
      {
        if (i == index) continue;
    
        double distance = CalculateDistance (index, i);
        if (distance < minDistance)
        {
          minDistance = distance;
          nearestIndex = i;
        }
      }
    
      return nearestIndex;
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    CalculateDistance()方法用于计算种群中索引为idx1和idx2两个解之间的欧氏距离。首先将变量distanceSum初始化为 0,该变量用于累加坐标差值的平方和。通过"for"循环遍历解的所有坐标维度,在每次循环中,计算idx1与idx2对应坐标之间的差值,并将该差值的平方累加到distanceSum中.

    循环结束后,该方法返回distanceSum的平方根,即两个解之间的欧氏距离。最终,该方法返回一个数值,用于表示两个解在搜索空间中的“距离”。该值越大,说明两个解相距越远。

    //——————————————————————————————————————————————————————————————————————————————
    double C_AO_BRO::CalculateDistance (int idx1, int idx2)
    {
      double distanceSum = 0.0;
    
      for (int c = 0; c < coords; c++)
      {
        double diff = a [idx1].c [c] - a [idx2].c [c];
        distanceSum += diff * diff;
      }
    
      return MathSqrt (distanceSum);
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    CalculateStandardDeviations()方法用于计算种群中每个解各维度坐标的标准差,并将结果存入sdValues数组中。首先调整输入数组sdValues的大小,使其能够存储每个“维度”(coords)坐标对应的标准差。之后,通过循环遍历每个坐标维度并计算标准差。该方法会先重置当前坐标的偏差平方和,再重置其均值。通过循环累加种群中所有解在当前坐标c上的数值,接下来,计算该坐标的平均值。 

    计算偏差平方和:循环遍历种群中的所有解,计算当前坐标相对于均值的偏差平方和。计算第i个解在第c维坐标上的数值与其均值的差值,将差值的平方累加到偏差平方和中。标准差计算公式:偏差平方和除以种群规模,再取平方根。计算结果存入sdValues数组的对应位置。

    最终,该方法计算出种群中每个坐标维度的数值离散程度,并存储在传入的sdValues数组中,标准差反映了各坐标值围绕均值的波动程度。

    //——————————————————————————————————————————————————————————————————————————————
    void C_AO_BRO::CalculateStandardDeviations (double &sdValues [])
    {
      ArrayResize (sdValues, coords);
    
      for (int c = 0; c < coords; c++)
      {
        double sum = 0.0;
        double mean = 0.0;
    
        // Calculate the average
        for (int i = 0; i < popSize; i++) mean += a [i].c [c];
    
        mean /= popSize;
    
        // Calculate the sum of squared deviations
        for (int i = 0; i < popSize; i++)
        {
          double diff = a [i].c [c] - mean;
          sum += diff * diff;
        }
    
        sdValues [c] = MathSqrt (sum / popSize);
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    ShrinkSearchSpace()方法基于坐标的标准差与当前最优解的位置来收缩搜索空间。形象地说,该方法会将搜索聚焦到已发现优质解的、更有潜力的区域。

    首先,计算标准差:通过调用CalculateStandardDeviations() 方法,计算种群中每个解各坐标维度的标准差,并将结果存入sdValues数组中。这一步用于衡量种群中各坐标值的离散程度。计算新边界:新的搜索边界以已找到的最优解为中心,宽度由标准差决定。如果标准差较小,搜索范围会紧紧围绕最优解收缩;反之,如果标准差较大,搜索范围则保持相对宽泛。有效性检查:收缩后的搜索空间不会超出初始设定的可行解范围。 

    //——————————————————————————————————————————————————————————————————————————————
    void C_AO_BRO::ShrinkSearchSpace ()
    {
      double sdValues [];
      CalculateStandardDeviations (sdValues);
    
      for (int c = 0; c < coords; c++)
      {
        // The new boundaries are centered around the best solution with a standard deviation width
        double newMin = cB [c] - sdValues [c];
        double newMax = cB [c] + sdValues [c];
    
        // Make sure the new bounds are within the original constraints
        if (newMin < rangeMin [c]) newMin = rangeMin [c];
        if (newMax > rangeMax [c]) newMax = rangeMax [c];
    
        // Update the boundaries
        rangeMin [c] = newMin;
        rangeMax [c] = newMax;
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    


    测试结果

    测试结果表明,该算法在Hilly函数和Forest函数上表现相当不错,但在离散型Megacity函数上,收敛速度要弱得多。

    BRO|Battle Royale Optimizer|50.0|3.0|
    =============================
    5 Hilly's; Func runs: 10000; result: 0.7494493002235458
    25 Hilly's; Func runs: 10000; result: 0.4983307394255448
    500 Hilly's; Func runs: 10000; result: 0.27994639979348446
    =============================
    5 Forest's; Func runs: 10000; result: 0.6962444245506945
    25 Forest's; Func runs: 10000; result: 0.3845619185097379
    500 Forest's; Func runs: 10000; result: 0.20427058729050862
    =============================
    5 Megacity's; Func runs: 10000; result: 0.3815384615384616
    25 Megacity's; Func runs: 10000; result: 0.21107692307692308
    500 Megacity's; Func runs: 10000; result: 0.10607692307692404
    =============================
    总分:3.51150 (39.02%)

    可视化结果表明,在最后一个离散型Megacity函数上,算法的结果值分布较为分散,搜索能力也相对较弱。

    Hilly值

    BRO在Hilly测试函数上

    Forest值

    BRO在Forest测试函数上

    Megacity值

    BRO在Megacity测试函数上

    根据测试结果,BRO算法在各类基于种群的优化算法排行榜中位列最后一名。

    # AO 描述 Hilly值 Hilly
    最终
    Forest值 Forest
    最终
    Megacity (离散) Megacity
    最终
    最终
    结果
    % of
    最大
    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 SRA 成功餐饮经营者算法 (joo) 0.96883 0.63455 0.29217 1.89555 0.94637 0.55506 0.19124 1.69267 0.74923 0.44031 0.12526 1.31480 4.903 54.48
    21 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
    22 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
    23 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
    24 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
    25 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
    26 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
    27 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
    28 (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
    29 TSm 禁忌搜索M 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
    30 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
    31 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
    32 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
    33 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
    34 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
    35 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
    36 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
    37 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
    38 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
    39 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
    40 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
    41 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
    42 CFO 中央力优化 0.60961 0.54958 0.27831 1.43750 0.63418 0.46833 0.22541 1.32792 0.57231 0.23477 0.09586 0.90294 3.668 40.76
    43 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
    44 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
    45 BRO 大逃杀优化器 0.74945 0.49833 0.27995 1.52773 0.69624 0.38456 0.20427 1.28507 0.38154 0.21108 0.10608 0.69870 3.512 39.02
    RW 神经Boid优化算法2(joo 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


    总结

    BRO算法为元启发式优化提供了一种新颖思路,以大逃杀模式为隐喻,让解之间相互竞争,从而开辟了 “基于游戏” 的优化方法方向。该算法的优势在于:概念简洁、直观易懂、实现难度相对较低,能够基于种群统计特征自动收缩搜索空间,并采用最近邻思想开展局部竞争。BRO算法是一种极具潜力的优化方法,其应用潜力远未被充分挖掘。

    标签

    图例3. 算法在相应测试中的颜色渐变表示

    图表

    图例4. 算法测试结果的直方图(评分范围为0到100,越高越好,其中100为理论上的最高可能得分,档案中附有计算排名表的脚本)

    BRO的优缺点:

    优点:

    1. 这是个有趣的理念。
    2. 实现简单。
    3. 极具发展前景。

    缺点:

    1. 在离散函数上表现不佳。

    文章附有一个包含当前版本算法代码的归档文件。本文作者对标准算法描述的绝对准确性不承担责任。为提升搜索能力,已经对其中的许多算法进行了修改。文章中表述的结论和论断都是基于实验的结果。


    文中所用的程序

    # 名称 类型 描述
    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_BRO.mq5
    脚本 BRO测试

    本文由MetaQuotes Ltd译自俄文
    原文地址: https://www.mql5.com/ru/articles/17688

    附加的文件 |
    BRO.zip (188.93 KB)
    最近评论 | 前往讨论 (1)
    Juan Guillermo Marulanda Mesa
    Juan Guillermo Marulanda Mesa | 23 1月 2026 在 15:11
    它看起来非常有趣,我打算试一试,看看我一直在测量的几个因素组合的最优解。
    交易策略 交易策略
    各种交易策略的分类都是任意的,下面这种分类强调从交易的基本概念上分类。
    图论:Dijkstra(迪杰斯特拉)算法在交易中的应用 图论:Dijkstra(迪杰斯特拉)算法在交易中的应用
    Dijkstra(迪杰斯特拉)算法是图论中一种经典的最短路径解决方案,它可以通过对市场网络进行建模来优化交易策略。交易者可以利用它从 K 线图表数据中找到最高效的路线。
    新手在交易中的10个基本错误 新手在交易中的10个基本错误
    新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
    MQL5交易工具(第七部分):用于多品种持仓与账户监控的信息仪表盘 MQL5交易工具(第七部分):用于多品种持仓与账户监控的信息仪表盘
    在本文中,我们将使用MQL5开发一款信息仪表盘,用于监控多品种持仓以及账户关键指标,如余额、净值和可用保证金。我们将实现一个支持排序的实时刷新表格、CSV导出功能,以及发光表头效果,以提升工具的实用性与视觉体验。