English Русский Español Deutsch 日本語 Português
preview
人工蜂巢算法(ABHA):理论及方法

人工蜂巢算法(ABHA):理论及方法

MetaTrader 5示例 | 27 二月 2025, 12:53
745 0
Andrey Dik
Andrey Dik
内容
  1. 引言
  2. 算法的实现
  3. 结论


1. 引言

在之前的文章中,我们已经考虑了人工蜂群(ABC)算法,这是自然启发下创建高效计算方法的一个显著例子。蜂群不仅仅是一群昆虫,而是一个高度组织的系统,其中每只蜜蜂都执行其独特的角色。一些蜜蜂成为侦察蜂,探索周围区域寻找食物,而其他蜜蜂则承担采集者的角色,收集花蜜和花粉。这种合作形式使蜂群在寻找资源时更加高效。

这里考虑的新型人工蜂巢算法提供了对蜜蜂觅食行为更全面和深入的观察,展示了集体互动和角色分配如何促进寻找新食物来源的过程。它展示了个体之间的互动如何带来更高效的结果。该算法更仔细地观察了蜂群中的个体角色。

ABHA的主要目标是在高维空间中寻找最优解,其中函数可能有许多局部极小值和极大值。这使得优化问题特别具有挑战性,因为传统方法可能会陷入局部极值而无法达到全局最优。ABHA算法从蜜蜂使用的高效觅食策略中汲取灵感。在自然界中,蜜蜂使用集体方法来高效地寻找花蜜来源,这一原理已被改编为创建一个可以改进寻找最优解过程的算法。

ABHA结构包括反映蜜蜂行为动态的各种状态。其中一种状态是“实验状态”,在此状态下蜜蜂交换它们找到的食物来源信息。这种状态促进了对多维空间中最富饶区域知识的积累。另一个重要状态是“搜索状态”,此时蜜蜂积极地探索空间寻找最佳来源,利用从同伴那里收到的信息。

人工蜂巢算法(ABHA)是由Andrés Muñoz领导的研究小组在2009年开发的。它旨在解决连续优化问题。


2. 算法的实现

ABHA是一种有趣的方法,它使用与蜜蜂行为的类比来解决连续搜索空间中的困难优化问题。让我们来看看算法的基本概念:

1. 蜜蜂行为建模

  • ABHA基于个体蜜蜂行为的模型。算法中的每个智能体(蜜蜂)遵循一套行为规则来确定它应该采取的行动。

2. 蜂巢内的互动

  • ABHA的主要关注点是蜜蜂之间的互动。
  • 蜜蜂交换它们找到的解决方案的信息。

该算法使用四种状态(角色)的蜜蜂,这些可以被视为不同类型的蜜蜂行为。为了清晰起见,方便以表格形式展示这些状态:
蜜蜂的状态
行为类型
新手
位于“蜂巢”(一个抽象的位置,信息在此交换)中,没有关于食物来源的信息。
有经验的   拥有关于食物来源的信息并可以分享它。
搜索  寻找比当前更好的食物来源。
食物来源 评估其食物来源的盈利能力,并决定是否值得宣布。

这些状态中的每一个都反映了蜜蜂在寻找和利用食物来源时行为的不同方面。每只蜜蜂的状态代表了相应蜜蜂遵循的一套规则:

蜜蜂的状态   改变蜜蜂在空间中位置的规则
新手
蜜蜂可以发起随机搜索或跟随舞蹈(如果可用)。如果没有关于食物来源的信息,它可能会开始随机搜索。
有经验的 如果关于食物来源的信息有效,蜜蜂可以通过舞蹈将其传递给其他蜜蜂。如果信息无效,它可能会开始随机搜索。
搜索 蜜蜂使用关于方向和步长的信息改变其位置,直到找到最好的食物来源。
食物来源 蜜蜂评估来源的盈利能力,如果不符合标准,可能会改变搜索方向。

并非所有蜜蜂都能分享关于食物来源的信息,也不是每只蜜蜂都能从其他有此能力的蜜蜂那里接收信息。有两种类型的蜜蜂具有接收或传递关于食物来源信息的能力:

1. 具有传递信息的能力:

  • 有经验的——如果关于食物来源的信息有效,通过舞蹈向其他蜜蜂传递信息。

2. 具有通过其他蜜蜂的舞蹈接收信息的能力:

  • 新手——如果可用,可能会跟随舞蹈以获取关于食物来源的信息。
  • 有经验的 ——能够通过舞蹈从其他蜜蜂那里接收信息,并拥有关于食物来源的信息。

蜜蜂可以根据与其经验和食物来源信息相关的条件改变它们的状态。下面我们列出蜜蜂的类型以及它们可以在何种条件下从一个状态转换到另一个状态:

1. 新手

  • 进入有经验的状态。如果一个新手通过其他蜜蜂的舞蹈获得了关于高盈利食物来源的信息,它可能会转变为有经验的状态。
  • 进入搜索状态。如果一个新手没有收到关于食物来源的信息,它可能会开始自行搜索,并进入搜索状态。

2. 有经验的

  • 进入搜索状态。 如果关于当前食物来源的信息不够好(例如,当前的适应度值低于阈值),蜜蜂可能会进入搜索状态以寻找新来源。
  • 进入食物来源状态。 如果关于食物来源的信息得到确认(例如,当前的适应度值高且稳定),蜜蜂可能会切换到食物来源状态,更深入地分析来源。

3. 搜索

  • 进入食物来源状态。 如果搜索的蜜蜂找到了具有良好特性的食物来源(例如,当前的适应度值优于阈值),它可以切换到食物来源状态,定期评估来源的盈利能力。
  • 进入新手状态。如果搜索的蜜蜂没有找到任何食物来源或信息不够有价值,它可能会恢复为新手状态。

4. 食物来源

  • 进入搜索状态。如果当前食物来源被证明是不切实际的(例如,当前的适应度值比阈值更差),蜜蜂可能会切换到搜索状态以寻找新来源。
  • 进入有经验的状态。如果食物来源蜜蜂找到了证明有益的食物来源,它可能会进入有经验的状态,将信息传递给其他蜜蜂。

这些状态转换允许算法根据个体在解决方案空间中的位置动态改变其搜索策略,并有效交换关于食物来源的信息。

食物来源”和蜜蜂“舞蹈”概念在算法中扮演着重要角色。在算法的上下文中,“食物来源”代表优化问题的潜在解决方案:

1. 每个“食物来源”对应于某个位置,代表搜索空间中优化问题的可能解决方案。2. 食物来源的“质量”或“盈利能力”由该点的目标函数值决定。目标函数值越高,代表“盈利能力”越大的食物来源。3. 算法中的蜜蜂搜索并利用最“盈利”的食物来源——对应于目标函数最佳值的位置。
4. 食物来源的枯竭意味着在搜索空间的给定点找不到更好的解决方案,蜜蜂应该转向寻找新的、更有希望的区域。

在算法中,“舞蹈”是蜜蜂交换关于找到的“食物来源”信息的一种方式。这是它的发生方式:

  • 当一只蜜蜂发现有希望的“食物来源”时,它返回“蜂巢”并进行“舞蹈”。
  • 舞蹈”的持续时间取决于所发现食物来源的“盈利能力”——解决方案越好,它“舞蹈”的时间就越长。
  • 蜂巢中的其他蜜蜂可能会听到这个“舞蹈”并获得有关食物来源的信息。蜜蜂跟随“舞蹈”的概率取决于来源的“盈利能力”。

因此,在ABHA算法中,“食物来源”是优化问题潜在解决方案的类似物,而其“盈利能力”由搜索空间中相应点的目标函数值决定,“舞蹈”是蜜蜂之间传递有关搜索过程中找到的最有望解决方案的信息的一种方式。

在ABHA算法中,每种类型的蜜蜂使用前一步骤、当前步骤和最佳适应度(或成本)值如下:

蜜蜂的状态 
新手
有经验的
搜索
食物来源
当前成本
用于进入有经验的或搜索状态。
如果当前值很高且信息有效,它可以通过舞蹈将这些信息传递给其他蜜蜂。
蜜蜂使用其当前适应度值来评估其当前位置,并决定是继续搜索还是改变方向。
如果当前值低于阈值,它可能决定该来源不够好并开始寻找新的来源。
先前值
未使用
蜜蜂将当前值与先前值进行比较,以确定情况是否得到改善。如果当前值更好,它可能会增加传递信息的概率。
蜜蜂将当前值与先前值进行比较,以确定情况是否得到改善。如果当前值更好,它可能会继续朝同一方向前进。
未使用
最佳值
未使用
蜜蜂可以使用最佳值来评估是否继续探索给定的食物来源或寻找新的食物来源。
蜜蜂使用最佳值来确定当前食物来源是否更有利可图。这有助于它做出是否停留或继续搜索的决定。
蜜蜂使用最佳值来决定是继续开发当前食物来源还是转移到有经验的状态。

每种类型的蜜蜂在不同的迭代中使用适应度信息来做出决策并转移到不同的状态。

在算法中,动作选择概率,例如随机搜索的概率、跟随舞蹈的概率和放弃来源(或留在来源附近)的概率,在整个优化过程中动态计算。这些概率帮助智能体(蜜蜂)根据当前信息和环境状态做出如何行动的决策。

计算概率:

1. 随机搜索的概率 (Psrs)。蜜蜂开始随机搜索而不是跟随舞蹈或留在当前食物来源的概率。

      2. 跟随舞蹈的概率 (Prul)。蜜蜂跟随另一只蜜蜂的舞蹈的概率。

          3. 放弃来源的概率 (Pab)。蜜蜂留在当前食物来源附近或放弃它的概率。

              处于不同状态的蜜蜂以不同的方式使用概率,每个状态的概率也不同:

              1. 新手

              • Psrs:高,因为蜜蜂没有关于其他来源的信息,可以开始随机搜索。
              • Prul:如果其他蜜蜂在跳舞,可以使用,但概率将取决于可用的信息。
              • Pab:不适用,因为蜜蜂尚未找到食物来源。

              2. 有经验的

              • Psrs:低,因为蜜蜂已经掌握了关于来源的信息。
              • Prul:如果来源信息被认为是有效的,用于向其他蜜蜂传递信息。
              • Pab:可以用来决定是否继续探索当前来源或在盈利低时放弃它。

               3. 搜索

              • Psrs:如果蜜蜂没有找到令人满意的来源,可以使用。
              • Prul:如果蜜蜂决定跟随另一只蜜蜂的舞蹈以找到新来源,可以使用。
              • Pab:用于评估是否继续搜索或返回“蜂巢”。

               4. 食物来源

              • Psrs:低,因为蜜蜂已经找到了来源。
              • Prul:如果来源被认为是有利可图的,用于向其他蜜蜂传递关于有效来源的信息。
              • Pab:如果来源没有产生令人满意的结果,则概率高,这可能导致决定放弃它。

              希望我已经涵盖了蜜蜂行为的所有细微差别,现在可以开始编写伪代码了。

              初始化:
              设置算法参数(popSize,maxSearchAttempts,abandonmentRate等)
              创建具有随机位置的智能体(蜜蜂)种群
              将每个智能体(蜜蜂)的初始状态设置为新手

              主循环:
              直到达到停止条件:
              对于每个个体:
              根据当前状态执行操作:
              新手:随机搜索或跟随舞蹈
              有经验的:随机搜索,跟随舞蹈或局部搜索
              搜索:向给定方向移动
              寻找食物:在最佳位置周围进行局部搜索
                          
              评估个体适应度
              如果找到,更新最佳全局解决方案

              计算概率和决策的平均成本

              对于每个个体:

              更新状态:
              新手:过渡到有经验的或搜索
              有经验的:可能过渡到食物来源或搜索
              搜索:可能过渡到新手或食物来源
              食物来源:可能过渡到搜索或有经验的

              更新最佳个人位置和值

              为个体计算概率
              计算平均成本

              现在让我们开始编写算法代码。ABHA逻辑相当复杂,代码量很大,因此我们将尽可能详细地描述工作中涉及的结构、类和方法。

              S_ABHA_Agent结构代表基于蜜蜂行为的算法中的“蜜蜂”智能体。结构:

              1. BeeState枚举定义了蜜蜂的各种状态:

              • stateNovice - 蜜蜂刚开始活动时的新手状态。
              • stateExperienced - 蜜蜂已经积累了一些经验的有经验的状态。
              • stateSearch - 蜜蜂积极寻找食物来源的搜索状态。
              • stateSource - 在来源附近及其定期评估的状态。

              2. 结构字段:

              • position [] - 蜜蜂在空间中当前位置的数组。
              • bestPosition [] - 蜜蜂在空间中最佳位置的数组。
              • direction [] - 蜜蜂移动方向的数组。
              • cost - 当前食物来源质量。
              • prevCost - 上一个食物来源质量。
              • bestCost - 找到的最佳食物来源质量。
              • stepSize - 蜜蜂沿坐标移动时的步长比例。
              • state - 蜜蜂的当前状态,表示为整数。
              • searchCounter - 蜜蜂在搜索状态下的动作计数器。

              3. 设置概率的结构字段:

              • pab - 留在食物来源附近的概率。
              • p_si - 其他蜜蜂选择这只蜜蜂的舞蹈的动态概率。
              • p_srs - 随机搜索概率。
              • p_rul - 跟随舞蹈的概率。
              • p_ab - 留在食物来源附近的概率。

              4. Init方法:

              • 通过接受coords坐标数和initStepSize初始步长来初始化智能体(蜜蜂)。
              • 该方法为数组分配内存,为结构的所有成员设置初始值,包括状态、计数器和概率。

              S_ABHA_Agent结构用于模拟算法中蜜蜂的行为,其中蜜蜂可以处于不同的状态,探索空间以寻找食物,并与其他蜜蜂互动。初始化结构允许我们设置启动算法所需的初始参数。

              //——————————————————————————————————————————————————————————————————————————————
              struct S_ABHA_Agent
              {
                  enum BeeState
                  {
                    stateNovice      = 0,    // Novice state
                    stateExperienced = 1,    // Experienced state
                    stateSearch      = 2,    // Search state
                    stateSource      = 3     // Food source state
                  };
              
                  double position        []; // Current position of the bee
                  double bestPosition    []; // Best bee position found
                  double direction       []; // Bee movement direction vector
                  double cost;               // Current food source quality
                  double prevCost;           // Previous food source quality
                  double bestCost;           // Best food source found quality
                  double stepSize;           // Step ratio in all coordinates during a bee movement
                  int    state;              // Bee's current state
                  int    searchCounter;      // Counter of the bee actions in the search state
              
                  double pab;                // Probability of remaining near the source
                  double p_si;               // Dynamic probability of other bees choosing this bee's dance
              
                  double p_srs;              // Random search probability
                  double p_rul;              // Probability of following the dance
                  double p_ab;               // Probability of source rejection
              
                  void Init (int coords, double initStepSize)
                  {
                    ArrayResize (position,        coords);
                    ArrayResize (bestPosition,    coords);
                    ArrayResize (direction,       coords);
                    cost              = -DBL_MAX;
                    prevCost          = -DBL_MAX;
                    bestCost          = -DBL_MAX;
                    state             = stateNovice;
                    searchCounter     = 0;
                    pab               = 0;
                    p_si              = 0;
                    p_srs             = 0;
                    p_rul             = 0;
                    p_ab              = 0;
              
                    stepSize        = initStepSize;
                  }
              };
              //——————————————————————————————————————————————————————————————————————————————
              

              C_AO_ABHA 类派生自 C_AO 基类,这意味着它使用了在父类中定义的功能。类的描述:

              1. C_AO_ABHA () 构造函数:

              • 设置参数,如种群大小(popSize)、最大搜索尝试次数(maxSearchAttempts)、不同概率的比率和初始步长(initialStepSize)。
              • 初始化 params 数组,其中包含算法参数。

              2. SetParams () 方法根据存储在 params 数组中的值设置算法参数的值。

              3. Init () 方法通过输入搜索范围的最小值和最大值、搜索步长和纪元数来初始化算法。 

              4. Moving ()Revision () 方法是设计用来实现智能体(蜜蜂)移动逻辑和修订找到的解决方案的方法。

              5. 类成员:

              • maxSearchAttempts - 最大搜索尝试次数。
              • abandonmentRate - 停留在食物来源附近的概率的步长变化。
              • randomSearchProbability - 随机搜索概率。
              • stepSizeReductionFactor - 步长减少比率。
              • initialStepSize - 初始步长。
              • S_ABHA_Agent agents [] - 参与算法的智能体(蜜蜂)数组。
              • avgCost - 找到的解决方案的平均成本。

              6. 蜜蜂行为的方法:

              • ActionRandomSearch () - 在给定范围内进行随机搜索。
              • ActionFollowingDance () - 跟随另一只蜜蜂的舞蹈。
              • ActionMovingDirection () - 考虑到步长,朝给定方向移动。
              • ActionHiveVicinity () - 在食物来源附近移动。

              7. 蜜蜂在不同状态下的活动方法:StageActivityNovice ()StageActivityExperienced ()StageActivitySearch ()StageActivitySource () 根据蜜蜂的状态决定蜜蜂的行为。

              8. 更改蜜蜂状态的方法:ChangingStateForNovice ()ChangingStateForExperienced ()ChangingStateForSearch ()ChangingStateForSource () 根据它们的活动更改蜜蜂的状态。

              9. 计算方法:

              • CalculateProbabilities () - 计算蜜蜂行为的概率。
              • CalculateAverageCost () - 计算找到的解决方案的平均成本。

              C_AO_ABHA 类实现了基于蜜蜂行为的优化算法,并涵盖了蜜蜂行为的各个方面,如移动、决策和状态变化。

              //——————————————————————————————————————————————————————————————————————————————
              class C_AO_ABHA : public C_AO
              {
                public:
                C_AO_ABHA ()
                {
                  ao_name = "ABHA";
                  ao_desc = "Artificial Bee Hive Algorithm";
                  ao_link = "https://www.mql5.com/en/articles/15347";
              
                  popSize                 = 10;
              
                  maxSearchAttempts       = 10;
                  abandonmentRate         = 0.1;
                  randomSearchProbability = 0.1;
                  stepSizeReductionFactor = 0.99;
                  initialStepSize         = 0.5;
              
                  ArrayResize (params, 6);
                  params [0].name = "popSize";                 params [0].val = popSize;
              
                  params [1].name = "maxSearchAttempts";       params [1].val = maxSearchAttempts;
                  params [2].name = "abandonmentRate";         params [2].val = abandonmentRate;
                  params [3].name = "randomSearchProbability"; params [3].val = randomSearchProbability;
                  params [4].name = "stepSizeReductionFactor"; params [4].val = stepSizeReductionFactor;
                  params [5].name = "initialStepSize";         params [5].val = initialStepSize;
                }
              
                void SetParams ()
                {
                  popSize                 = (int)params [0].val;
              
                  maxSearchAttempts       = (int)params [1].val;
                  abandonmentRate         = params      [2].val;
                  randomSearchProbability = params      [3].val;
                  stepSizeReductionFactor = params      [4].val;
                  initialStepSize         = params      [5].val;
                }
              
                bool Init (const double &rangeMinP  [], //minimum search range
                           const double &rangeMaxP  [], //maximum search range
                           const double &rangeStepP [], //step search
                           const int     epochsP = 0);  //number of epochs
              
                void Moving   ();
                void Revision ();
              
                //----------------------------------------------------------------------------
                int    maxSearchAttempts;
                double abandonmentRate;
                double randomSearchProbability;
                double stepSizeReductionFactor;
                double initialStepSize;
              
                S_ABHA_Agent agents [];
              
                private: //-------------------------------------------------------------------
                double avgCost;
              
                //Types of bees' actions----------------------------------------------------------
                double ActionRandomSearch       (int coordInd);                      //1. Random search (random placement in a range of coordinates)
                double ActionFollowingDance     (int coordInd, double val);          //2. Follow the dance (move in the direction of the dancer)
                double ActionMovingDirection    (S_ABHA_Agent &agent, int coordInd); //3. Move in a given direction with a step
                double ActionHiveVicinity       (int coordInd, double val);          //4. Move in the vicinity of a food source
              
                //Actions of bees in different states----------------------------------------
                void   StageActivityNovice      (S_ABHA_Agent &agent); //actions 1 or 2
                void   StageActivityExperienced (S_ABHA_Agent &agent); //actions 1 or 2 or 4
                void   StageActivitySearch      (S_ABHA_Agent &agent); //actions 3
                void   StageActivitySource      (S_ABHA_Agent &agent); //actions 4
              
                //Change bees' state----------------------------------------------------
                void ChangingStateForNovice      (S_ABHA_Agent &agent);
                void ChangingStateForExperienced (S_ABHA_Agent &agent);
                void ChangingStateForSearch      (S_ABHA_Agent &agent);
                void ChangingStateForSource      (S_ABHA_Agent &agent);
              
                void CalculateProbabilities ();
                void CalculateAverageCost   ();
              };
              //——————————————————————————————————————————————————————————————————————————————
              

              Init 方法是 C_AO_ABHA 类负责初始化 ABHA 算法的。让我们一步步分解:

              1. 方法参数:

              • rangeMinP [] - 最小搜索范围值数组。这些是将要优化的每个变量的下限。
              • rangeMaxP [] - 最大搜索范围值数组。这些是每个变量的上限。
              • rangeStepP [] - 搜索步长数组。这些值决定了搜索过程中变量的变化量。
              • epochsP - 算法覆盖的纪元(迭代)数。 

              2. 如果初始化成功,该方法返回 'true',否则返回 'false'。

              方法逻辑:

              • 调用带有搜索范围参数的 StandardInit 方法。此方法执行标准初始化操作,例如设置搜索界限和步长。如果初始化失败,Init 方法终止执行并返回 'false'。
              • ArrayResize 方法更改“agents”数组的大小,该数组代表算法中的蜜蜂(智能体)。数组大小设置为 popSize,这决定了参与优化的智能体(蜜蜂)数量。
              • 循环初始化“agents”数组中的每个智能体(蜜蜂)。为每个智能体调用 Init 方法,为其设置了初始坐标(来自 "coords" 数组)和 initialStepSize 初始步长。这一步决定了智能体在搜索期间可以移动的距离。

              C_AO_ABHA 类的 Init 方法执行以下任务:

              • 检查搜索参数的标准初始化是否成功。
              • 根据给定的蜜蜂数量调整智能体数组的大小。
              • 使用其自身的 Init 方法初始化每个智能体(蜜蜂),设置算法工作所需的初始参数。

              如果所有步骤都成功完成,该方法返回 "true",这表明算法初始化成功。

              //——————————————————————————————————————————————————————————————————————————————
              bool C_AO_ABHA::Init (const double &rangeMinP  [], //minimum search range
                                    const double &rangeMaxP  [], //maximum search range
                                    const double &rangeStepP [], //step search
                                    const int     epochsP = 0)   //number of epochs
              {
                if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
              
                ArrayResize (agents, popSize);
                for (int i = 0; i < popSize; i++)
                {
                  agents [i].Init (coords, initialStepSize);
                }
                return true;
              }
              //————————————————————
              

              接下来是 C_AO_ABHA 类的 Moving 方法,它实现了算法中智能体(蜜蜂)移动阶段。Moving 方法不接受任何参数,也不返回任何值。它控制优化过程中智能体(蜜蜂)的移动。方法逻辑:

              1. 初始化。

              • 检查 revision 变量。如果是 'false',则这是第一次方法调用,应该初始化智能体位置。
              • 生成初始位置 - 嵌套循环遍历所有智能体和坐标。对于每个坐标:
                • 在指定范围内(rangeMinrangeMax)生成一个 val 随机值。
                • 然后使用 SeInDiSp 调整该值,将其设置为给定步长的允许范围内。
                • 设置智能体的当前位置和最佳位置(开始时它们是相同的)。
                • 生成智能体移动的随机方向。
              • 初始化完成后,将 revision 设置为 'true',方法终止。

              2. 智能体(蜜蜂)移动的基本逻辑。根据状态移动智能体(蜜蜂):

              • 使用 switch 确定每个智能体(蜜蜂)的当前状态(新手、有经验的、搜索或食物来源)。根据状态,调用适当的方法,该方法控制智能体的行为(例如,StageActivityNoviceStageActivityExperienced 等)。
              • 根据状态执行操作后,使用 SeInDiSp 更新智能体的位置,以保持在可接受的范围内。

              3. 循环更新 a 数组,将智能体的当前位置复制到 a 数组的相应元素中。

              Moving 方法的最终意义,它控制 ABHA 算法中智能体的移动。它首先在这是第一次方法调用时初始化智能体的位置,然后根据它们的状态更新它们的位置,并包括:

              • 生成随机起始位置。
              • 根据智能体的状态确定它们的行为。
              • a 数组中更新智能体的当前位置。 

              该方法是优化过程中智能体动态行为的关键和控制方法,用于调用其他蜜蜂状态方法。

              //——————————————————————————————————————————————————————————————————————————————
              void C_AO_ABHA::Moving ()
              {
                //----------------------------------------------------------------------------
                if (!revision)
                {
                  double val = 0.0;
              
                  for (int i = 0; i < popSize; i++)
                  {
                    for (int c = 0; c < coords; c++)
                    {
                      val = u.RNDfromCI (rangeMin [c], rangeMax [c]);
                      val = u.SeInDiSp (val, rangeMin [c], rangeMax [c], rangeStep [c]);
              
                      agents [i].position     [c] = val;
                      agents [i].bestPosition [c] = val;
                      agents [i].direction    [c] = u.RNDfromCI (-(rangeMax [c] - rangeMin [c]), (rangeMax [c] - rangeMin [c]));
              
                      a [i].c [c] = val;
                    }
                  }
                  revision = true;
                  return;
                }
                //----------------------------------------------------------------------------
                for (int i = 0; i < popSize; i++)
                {
                  switch (agents [i].state)
                  {
                    //------------------------------------------------------------------------
                    //Novice
                    case S_ABHA_Agent::stateNovice:
                    {
                      StageActivityNovice (agents [i]);
                      break;
                    }
                      //------------------------------------------------------------------------
                      //Experienced
                    case S_ABHA_Agent::stateExperienced:
                    {
                      StageActivityExperienced (agents [i]);
                      break;
                    }
                      //------------------------------------------------------------------------
                      //Search
                    case S_ABHA_Agent::stateSearch:
                    {
                      StageActivitySearch (agents [i]);
                      break;
                    }
                      //------------------------------------------------------------------------
                      //Food source
                    case S_ABHA_Agent::stateSource:
                    {
                      StageActivitySource (agents [i]);
                      break;
                    }
                  }
                  //--------------------------------------------------------------------------
                  for (int c = 0; c < coords; c++)
                  {
                    agents [i].position [c] = u.SeInDiSp (agents [i].position [c], rangeMin [c], rangeMax [c], rangeStep [c]);
                    a      [i].c        [c] = agents [i].position [c];
                  }
                }
                for (int i = 0; i < popSize; i++) for (int c = 0; c < coords; c++) a [i].c [c] = agents [i].position [c];
              }
              //——————————————————————————————————————————————————————————————————————————————
              
              

              Revision 方法是 C_AO_ABHA 类负责更新算法中智能体状态的方法,执行与评估和更新智能体位置和状态相关的几个关键动作。Revision 方法不接受任何参数,也不返回任何值。它用于根据性能更新有关智能体状态和位置的信息。方法逻辑:

              1. 寻找最佳智能体:

              • ind 变量使用 -1 值初始化,以跟踪具有最佳成本的智能体索引。
              • 在寻找最佳智能体时,循环遍历所有 popSize智能体:
              • 如果 a [i].f 智能体成本超过当前 fB 最大值,则更新 fB 并保存 ind 索引。
              • 如果找到具有最佳成本的智能体(ind 不等于 -1),则调用 ArrayCopy 函数,该函数将最佳智能体的坐标复制到 cB 数组中。

              2. 循环遍历所有智能体,并根据 a 数组值更新他们的 agents[i].cost 成本。

              3. 调用 CalculateProbabilities 方法,根据他们当前的成本计算每个智能体的概率。这用于确定智能体在下一步将如何行动。

              4. 同样调用 CalculateAverageCost 方法。它计算所有智能体的平均成本,这对于蜜蜂分析自己的状态并转移到新状态是必要的。

              5. 循环遍历所有智能体,并根据他们当前的状态调用适当的方法来更改智能体状态 ChangingStateForNoviceChangingStateForExperienced 等。

              6. 循环遍历所有智能体,并检查智能体的当前值是否大于其最佳 bestCost

              • 如果是,更新 bestCost 并将智能体的当前位置复制到 bestPosition
              • 更新 prevCost 上一成本为 cost 当前成本。

              Revision 方法操作的最终意义,它负责更新算法中智能体的状态信息,并执行以下关键动作:

              1. 找到具有最佳成本的智能体并更新相应的变量。

              2. 更新所有智能体的价格。

              3. 根据当前值计算概率。

              4. 计算智能体的平均成本。

              5. 根据他们的表现更新智能体状态。

              6. 更新最佳智能体的价格和位置。

              该方法是算法的重要组成部分,因为它允许智能体根据成功与否来进行调整,并允许他们交换信息。

              //——————————————————————————————————————————————————————————————————————————————
              void C_AO_ABHA::Revision ()
              {
                //----------------------------------------------------------------------------
                int ind = -1;
              
                for (int i = 0; i < popSize; i++)
                {
                  if (a [i].f > fB)
                  {
                    fB = a [i].f;
                    ind = i;
                  }
                }
              
                if (ind != -1) ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY);
              
                //----------------------------------------------------------------------------
                for (int i = 0; i < popSize; i++) agents [i].cost = a [i].f;
              
                //----------------------------------------------------------------------------
                //Calculate the probabilities for bees at the current cost
                CalculateProbabilities ();
              
                //----------------------------------------------------------------------------
                //Calculate the average cost
                CalculateAverageCost ();
              
                //----------------------------------------------------------------------------
                //update bees' states (novice, experienced, search, source) 
                for (int i = 0; i < popSize; i++)
                {
                  switch (agents [i].state)
                  {
                    case S_ABHA_Agent::stateNovice:
                    {
                      ChangingStateForNovice (agents [i]);
                      break;
                    }
                    case S_ABHA_Agent::stateExperienced:
                    {
                      ChangingStateForExperienced (agents [i]);
                      break;
                    }
                    case S_ABHA_Agent::stateSearch:
                    {
                      ChangingStateForSearch (agents [i]);
                      break;
                    }
                    case S_ABHA_Agent::stateSource:
                    {
                      ChangingStateForSource (agents [i]);
                      break;
                    }
                  }
                }
                //----------------------------------------------------------------------------
                //Update the cost for bees
                for (int i = 0; i < popSize; i++)
                {
                  if (agents [i].cost > agents [i].bestCost)
                  {
                    agents [i].bestCost = agents [i].cost;
              
                    ArrayCopy (agents [i].bestPosition, agents [i].position);
                  }
                  agents [i].prevCost = agents [i].cost;
                }
              }
              //——————————————————————————————————————————————————————————————————————————————
              
              


              结论

              我们已经考虑了人工蜂巢算法(ABHA),详细分析了其运作原理,编写了算法的伪代码,并描述了结构、类以及初始化过程,还有 MovingRevision 方法。在下一篇文章中,我们将继续编写算法代码,并涵盖所有其他方法。和往常一样,我们将在测试函数上进行测试,并在评级表中总结算法的结果。

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

              附加的文件 |
              ABHA.zip (29.82 KB)
              开发回放系统(第 59 部分):新的未来 开发回放系统(第 59 部分):新的未来
              正确理解不同的想法可以让我们事半功倍。在本文中,我们将探讨为什么在服务与图表交互之前需要配置模板。此外,如果我们改进鼠标指标,这样我们就可以用它做更多的事情呢?
              开发回放系统(第 58 部分):重返服务工作 开发回放系统(第 58 部分):重返服务工作
              在回放/模拟器服务的开发和改进暂停之后,我们正在恢复该工作。现在我们已经放弃使用终端全局变量等资源,我们将不得不完全重组其中的一些部分。别担心,我们会详细解释这个过程,这样每个人都可以关注我们服务的发展。
              您应当知道的 MQL5 向导技术(第 23 部分):CNNs 您应当知道的 MQL5 向导技术(第 23 部分):CNNs
              卷积神经网络是另一种机器学习算法,倾向于专门将多维数据集分解为关键组成部分。我们看看典型情况下这是如何达成的,并探索为交易者在其它 MQL5 向导信号类中的可能应用。
              神经网络变得简单(第 94 部分):优化输入序列 神经网络变得简单(第 94 部分):优化输入序列
              在处理时间序列时,我们始终按其历史序列使用源数据。但这是最好的选项吗?有一种观点认为,改变输入数据顺序将提高训练模型的效率。在本文中,我邀请您领略其中一种优化输入序列的方法。