English Русский Español Deutsch 日本語 Português
preview
基于生物地理学的优化算法(BBO)

基于生物地理学的优化算法(BBO)

MetaTrader 5交易 |
18 0
Andrey Dik
Andrey Dik

内容

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


引言

在梳理各类优化算法的过程中,我对基于生物地理学的优化算法(BBO)产生了兴趣,该算法由丹・西蒙教授于 2008 年提出。BBO 算法的灵感来源于生物地理学,这是一门研究生物有机体地理分布规律的学科。描述物种分布模式的数学模型最早诞生于 20 世纪 60 年代。正如遗传算法借鉴生物遗传学、神经网络模仿生物神经元原理一样,BBO 算法依托生物地理学中的数学原理来求解优化问题。

在自然界的群岛环境中,宜居条件优越的岛屿(栖息地适宜度指数 HSI 较高)往往物种丰富,物种迁出率也更高;而生存环境恶劣的岛屿物种稀少,物种迁入率则更高。这种岛屿间物种迁徙的自然动态规律,构成了 BBO 算法优化机制的理论基础。该算法借助物种迁徙的思想在不同可行解之间交换特征信息,变异概率依托具备完备理论支撑的物种分布模型计算得出;优质解会主动共享自身特征,同时自身又具备较强的稳定性,不易被随意改动。这一特性也是该算法最具代表性的特点之一。

本文将对这套精妙的算法原理进行解析,完成代码实现,并对 BBO 算法的性能开展测试评估。


算法的实现

我们可以想象一片群岛,每座岛屿都栖息着不同种类的动物。 

1. 栖息地 = 岛屿 = 问题的可行解。算法中的每一座岛屿都代表一个可行解。如果设置 50 座岛屿,就对应 50 个不同的可行解。

2. 栖息地适宜度指数(HSI)= 岛屿的宜居程度 = 可行解的质量。拥有淡水、瓜果、宜人气候的富饶岛屿对应优质解(HSI 数值高)。没有水源的荒漠岛屿 = 劣质解(HSI 数值低)

3. 物种 = 可行解的特征属性。资源丰富的岛屿会孕育大量物种,而贫瘠岛屿由于栖息地多样性不足,存活的物种数量较少。

迁徙机制是如何运作的?现实举例:夏威夷这座富饶岛屿物种繁多,生物频繁迁徙至其他岛屿(迁出率高),但很少有外来生物迁入该岛(迁入率低,岛屿已趋于饱和)。无人荒岛物种稀少,生物很少向外迁徙(迁出率低),但经常会有新物种迁入(迁入率高,存在大量生存空间)。

映射到算法中:劣质解(物种少)→ 迁入率高 → 不断吸收优质解的特征。优质解(物种丰富)→ 迁出率高 → 向其他解共享自身特征。

再举一个生活中的例子:假设我们要在城市里寻找开店的最佳选址。每一座 “岛屿” 就代表一个候选选址。我们随机生成 50 个选址(岛屿),举例如下:

岛屿 1:选址较差,位于城郊
岛屿 2:位置极佳,地处市中心
第 50 座岛屿:位置中等偏上

我们为每个选址计算适宜度 HSI:岛屿 2(市中心)HSI=95,客流量大、交通便利;岛屿 1(城郊)HSI=20,客流量稀少。此时劣质的岛屿 1 迁入率高,会吸收优质岛屿 2 的部分特征。比如岛屿 2 的选址特点是 “临近地铁站”,那么岛屿 1 也会朝着靠近地铁站的方向优化选址。自然界有时会发生地震、海啸这类灾害,对应算法里可行解发生随机突变:店铺选址会直接更换到一个全新的位置,这种随机变化有助于发掘意料之外的优质可行解。

为什么中等质量的可行解发生突变的概率更低?在自然界中,像加拉帕戈斯群岛那样极度富饶的岛屿十分稀少且环境易变,极端贫瘠的岛屿同样罕见且不稳定,反而是环境中等的岛屿数量最多、稳定性最强。映射到算法中规则如下:

极优解(HSI=95):突变概率高
极劣解(HSI=5):突变概率高
中等可行解(HSI=50):突变概率低

排名前两位的最优岛屿(最优解)会被保护起来不参与突变,相当于设立 “自然保护区”。我们要避免丢失当前搜寻到的最优可行解。完整的优化流程如下:随机生成 50 组可行解(岛屿),按照优劣从高到低排序,劣质解向优质解学习特征,同时部分可行解会发生随机突变。BBO 算法通过通过模拟岛屿间物种分布/迁移的自然过程,以此搜寻最优解。下文附上该算法的运行原理示意图。

BBO

图例 1. BBO 算法运行原理 

本示意图展示内容如下:

  1. 三类岛屿:分别为富饶型、中等型、贫瘠型,各类岛屿栖息的物种数量各不相同。
  2. 迁徙过程:箭头表示物种在各个岛屿之间的迁移路径。
  3. 分步优化流程:展示从初始化到迭代循环的完整过程。
  4. 核心概念说明:包含图例注释与算法基本原理。

该示意图清晰展现:富饶岛屿(优质可行解)具备较高的物种迁出率,贫瘠岛屿(劣质可行解)具备较高的物种迁入率;可行解之间会发生特征交换,完整的优化循环由此运转。接下来我们编写伪代码。

1. 初始化:
- 设置各项参数:
     * 种群规模(栖息地总数)= 50
     * 最大迁入率 I = 1.0
     * 最大迁出率 E = 1.0
     * 基础变异概率 = 0.01
     * 精英解保留数量 = 2
     * 最大物种数量 = 50
     * 迭代次数
   
   - 随机生成 N 个栖息地(可行解)构成初始种群
   - 计算每个栖息地的栖息地适宜度指数(HSI)
   - 计算不同物种数量对应的栖息地生存概率

2. 主循环(按照设定迭代次数循环执行):
   
   2.1. 适应度评估与排序:
        - 计算每个栖息地的 HSI 值
        - 按照 HSI 值从高到低对所有栖息地排序
        - 保存当前最优解
   
   2.2. 迁移参数计算:
遍历第i个栖息地:
        - 计算该栖息地物种数量:Si = Smax × (N - rank_i) / N
    - 计算迁入率:λi = I × (1 - Si/Smax)
        - 计算迁出率:μi = E × (Si/Smax)
根据当前物种数量 Si 确定该栖息地的生存概率
   
   2.3. 迁移操作(可行解特征交换):
        遍历每个非精英栖息地:
        
        如果random_number < λi (栖息地迁入),那么:
           
           遍历每个决策变量 (SIV) j:
              
              如果random_number < λi:
                 - 选取一个提供特征的源栖息地:
                   * 累加除当前栖息地(H_i)外所有栖息地的迁出率总和
                   * 基于迁出率(μ)采用轮盘赌选择策略
                   * 以概率 μk/Σμ 选中栖息地(H_k)
                 
                 - 将源栖息地 Hk 的第 j 个变量复制到栖息地 H_i
              
        结束条件判断
           
           结束变量循环
        
        结束条件判断
        
结束栖息地循环
   
   2.4. 变异操作(探索全新可行解):
        遍历每个非精英栖息地(H_i):
        
        - 计算变异率:m_rate = m × (1 - probability_of_existence_i)
        
如果随机数小于变异率(random_number < m_rate),则:
           - 随机选取一个决策变量 j
           - 在合法取值范围内生成随机值替换该变量原有数值
        结束条件判断
        
        结束栖息地循环
   
   2.5. 种群替换与更新:
        - 重新计算所有栖息地的 HSI 数值
        - 更新当前搜索到的最优解
        - 保存本轮所有个体的适应度值,用于下一轮迭代

3. 返回搜索得到的最优可行解

现在我们只需要实现C_AO_BBO类,该类继承自C_AO基类,用于完成 BBO 算法的封装实现。继承特性意味着C_AO_BBO可以调用父类中已经封装好的优化基础功能。

该类包含一系列参数:种群规模参数以及 BBO 算法专属参数,具体包括:最大迁入率、最大迁出率(immigrationMax、emigrationMax)、变异概率(mutationProb)、保留的精英解数量(elitismCount)以及最大物种数量(speciesMax)。类的构造函数会为 BBO 相关参数赋予默认初始值,同时设置算法名称、功能描述以及该算法相关文献的链接。SetParams()方法可根据参数数组params中的数据对各项参数进行修改赋值。

核心方法:
  • Init():初始化算法,包含种群的创建与初始化、设定参数取值范围、迭代步长、迭代轮数,同时初始化用于存储栖息地数据的各类数组。
  • Moving():按照 BBO 算法原理,实现可行解在不同栖息地之间迁移的核心逻辑。
  • Revision():实现可行解(栖息地)的修正与调整逻辑。 
内部数据结构:
  • S_HabitatData:内部结构体,用于存储单个栖息地(可行解)的相关信息,包含物种数量、迁入率、迁出率以及生存概率。
  • habitatData:S_HabitatData类型数组,用来保存种群中每一个栖息地的全部数据。
  • probabilities:用于变异操作的概率数组。

私有方法封装了 BBO 算法各核心步骤的具体实现,包括种群初始化、迁移率计算、变异操作等。

//——————————————————————————————————————————————————————————————————————————————
class C_AO_BBO : public C_AO
{
  public: //--------------------------------------------------------------------
  ~C_AO_BBO () { }
  C_AO_BBO ()
  {
    ao_name = "BBO";
    ao_desc = "Biogeography-Based Optimization";
    ao_link = "https://www.mql5.com/en/articles/18354";

    popSize        = 50;     // population size (number of habitats)
    immigrationMax = 1.0;    // maximum immigration rate
    emigrationMax  = 1.0;    // maximum emigration rate
    mutationProb   = 0.5;    // mutation probability
    elitismCount   = 2;      // number of elite solutions
    speciesMax     = 50;     // maximum number of species

    ArrayResize (params, 6);

    params [0].name = "popSize";        params [0].val = popSize;
    params [1].name = "immigrationMax"; params [1].val = immigrationMax;
    params [2].name = "emigrationMax";  params [2].val = emigrationMax;
    params [3].name = "mutationProb";   params [3].val = mutationProb;
    params [4].name = "elitismCount";   params [4].val = elitismCount;
    params [5].name = "speciesMax";     params [5].val = speciesMax;
  }

  void SetParams ()
  {
    popSize        = (int)params [0].val;
    immigrationMax = params      [1].val;
    emigrationMax  = params      [2].val;
    mutationProb   = params      [3].val;
    elitismCount   = (int)params [4].val;
    speciesMax     = (int)params [5].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 ();

  //----------------------------------------------------------------------------
  double immigrationMax;    // maximum immigration rate
  double emigrationMax;     // maximum emigration rate
  double mutationProb;      // mutation probability
  int    elitismCount;      // number of elite solutions
  int    speciesMax;        // maximum number of species

  private: //-------------------------------------------------------------------
  struct S_HabitatData
  {
      int    speciesCount;     // number of species in the habitat
      double immigration;      // immigration rate
      double emigration;       // emigration rate
      double probability;      // probability of existence
  };

  S_HabitatData habitatData   [];  // data for each habitat
  double        probabilities [];  // probabilities for counting mutations

  // Auxiliary methods
  void   InitializePopulation ();
  void   CalculateRates       ();
  void   Migration            ();
  void   Mutation             ();
  double CalculateProbability (int speciesCount);
};
//——————————————————————————————————————————————————————————————————————————————

Init 方法用于在 BBO 算法正式运行前完成各项配置工作。该方法会执行基础初始化操作(参数校验与环境配置),为存储 “栖息地” 相关数据和迁移概率分配内存。随后根据不同物种数量计算并归一化相应的概率值。初始化执行成功则返回 true。

//——————————————————————————————————————————————————————————————————————————————
bool C_AO_BBO::Init (const double &rangeMinP  [],  // minimum values
                     const double &rangeMaxP  [],  // maximum values
                     const double &rangeStepP [],  // step change
                     const int     epochsP = 0)    // number of epochs
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;

  //----------------------------------------------------------------------------
  // Initialize arrays for each habitat
  ArrayResize (habitatData,   popSize);
  ArrayResize (probabilities, speciesMax + 1);

  // Calculate probabilities for different numbers of species
  double sum = 0.0;
  for (int i = 0; i <= speciesMax; i++)
  {
    probabilities [i] = CalculateProbability (i);
    sum += probabilities [i];
  }

  // Normalization of probabilities
  if (sum > 0)
  {
    for (int i = 0; i <= speciesMax; i++)
    {
      probabilities [i] /= sum;
    }
  }

  return true;
}
//——————————————————————————————————————————————————————————————————————————————

Moving 方法实现了 BBO 算法的主优化循环逻辑。首次调用该方法时,会先校验 “是否初始化” 标识位。若标识显示种群尚未创建,则执行种群初始化操作。包括随机生成多组可行解、评估各组解的适宜度,并初始化相关参数。初始化完成后,将该标识位重置。

初始化结束后,依次执行算法循环的标准步骤:按照适应度值对可行解种群排序,区分出最优个体与最差个体。这为后续的迁移、变异操作提供依据。这一阶段会根据各栖息地当前状态以及对应可行解的优劣,计算栖息地之间物种交换的各类概率与速率参数。以此管控物种从一个栖息地向另一个栖息地的 “迁移” 过程。同时完成各栖息地之间决策变量的交换。

最终,物种多样性匮乏的劣质解会从优质解中获取新的特征,实现对解空间的全局探索。迁移操作结束后,会对可行解执行随机变更(变异操作),用以维持种群多样性。变异概率由可行解当前状态与算法参数共同决定。单次循环末尾会保存当前所有可行解的适应度函数数值,供算法下一轮迭代的排序与数据分析使用。

//+----------------------------------------------------------------------------+
//| Basic optimization method                                                  |
//+----------------------------------------------------------------------------+
void C_AO_BBO::Moving ()
{
  // First iteration - initialization of the initial population
  if (!revision)
  {
    InitializePopulation ();
    revision = true;
    return;
  }

  // Main optimization
  // 1. Sort the population by HSI (fitness)
  static S_AO_Agent aTemp []; ArrayResize (aTemp, popSize);
  u.Sorting (a, aTemp, popSize);

  // 2. Calculate immigration and emigration rates
  CalculateRates ();

  // 3. Migration (exchange of SIVs between habitats)
  Migration ();

  // 4. Probability-based mutation
  Mutation ();

  // 5. Save state for the next iteration
  for (int i = 0; i < popSize; i++)
  {
    a [i].fP = a [i].f;
  }
}
//——————————————————————————————————————————————————————————————————————————————

Revision 方法用于更新种群中当前的最优解。该方法遍历当前种群内所有个体(可行解),将每个个体的适应度函数值与变量 fB 中存储的当前最优结果进行比对。

如果某个个体的适应度优于当前最优值,就用该值更新 fB,并将对应的解参数复制保存到最优解变量中。方法执行完毕后,该变量中始终会保存当前搜索到的最优可行解。

//+----------------------------------------------------------------------------+
//| Update the best solution                                                   |
//+----------------------------------------------------------------------------+
void C_AO_BBO::Revision ()
{
  // Find the best solution in the current population
  for (int i = 0; i < popSize; i++)
  {
    // Update the best solution
    if (a [i].f > fB)
    {
      fB = a [i].f;
      ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY);
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

InitializePopulation 方法负责为 BBO 算法创建初始可行解种群。该方法生成种群规模(popSize)数量的个体(栖息地),所有个体均匀分布在整个搜索空间内。

针对每一个个体,该方法在每个维度参数的最小值数组 rangeMin、最大值数组 rangeMax 限定范围内,随机生成坐标值(解参数)。通过 u.RNDfromCI 函数在指定区间内生成随机数。

随后将生成的坐标按照 rangeStep 数组规定的有效步长就近取整。保证所有可行解落在离散的合法搜索空间内。该步骤调用 SeInDiSp 函数实现。坐标初始化完成后,为每个个体初始化 habitatData 结构体,将物种数量、迁入率、迁出率、生存概率全部初始化为 0。这些参数后续用于优化过程中计算迁移率与变异概率。

//+----------------------------------------------------------------------------+
//| Initialize the initial population                                          |
//+----------------------------------------------------------------------------+
void C_AO_BBO::InitializePopulation ()
{
  // Initialize the initial population uniformly throughout the space
  for (int i = 0; i < popSize; i++)
  {
    for (int c = 0; c < coords; c++)
    {
      // Generate random coordinates within acceptable limits
      a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
      // Round to the nearest acceptable step
      a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
    }

    // Initialize habitat data
    habitatData [i].speciesCount = 0;
    habitatData [i].immigration  = 0.0;
    habitatData [i].emigration   = 0.0;
    habitatData [i].probability  = 0.0;
  }
}
//——————————————————————————————————————————————————————————————————————————————

CalculateRates 方法用于计算种群中每个栖息地的迁移率(迁入率、迁出率)以及栖息地的生存概率。

本方法采用线性模型,每个可行解对应的物种数量与其适应度成正比,性能越优异的可行解所拥有的物种数量越多。迁入率会随着物种数量的增加而递减:某个可行解的物种越丰富,接纳新个体的概率就越低。迁出率会随着物种数量的增加而递增:某个可行解的物种越丰富,物种向外迁出的概率就越高。

栖息地的生存概率根据预先设定好的各物种数量对应的概率值确定。如果物种数量超过设定的最大允许值,则将该栖息地的生存概率置为 0。

//+----------------------------------------------------------------------------+
//| Calculate immigration and emigration rates                                 |
//+----------------------------------------------------------------------------+
void C_AO_BBO::CalculateRates ()
{
  // For the linear migration model
  for (int i = 0; i < popSize; i++)
  {
    // The number of species is inversely proportional to the rank (the best solutions have more species)
    habitatData [i].speciesCount = speciesMax - (i * speciesMax / popSize);

    // The rate of immigration decreases as the number of species increases
    habitatData [i].immigration = immigrationMax * (1.0 - (double)habitatData [i].speciesCount / speciesMax);

    // The rate of emigration increases with the number of species
    habitatData [i].emigration = emigrationMax * (double)habitatData [i].speciesCount / speciesMax;

    // Probability of habitat existence
    if (habitatData [i].speciesCount <= speciesMax)
    {
      habitatData [i].probability = probabilities [habitatData [i].speciesCount];
    }
    else
    {
      habitatData [i].probability = 0.0;
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

Migration 方法用于实现种群内各个栖息地之间的迁移过程,也就是 SIV(栖息地适宜度指数变量,即可行解的坐标参数)的交换操作。该方法的核心思想是:迁入率高的栖息地(物种数量稀少),可以从迁出率高的其他栖息地(物种丰富)中借鉴特征变量。

方法会遍历种群内所有栖息地,但会跳过前elitismCount个被标记为精英的栖息地,精英个体不参与迁移操作。对于每一个非精英栖息地,会通过随机方式判断该栖息地在本轮迭代中是否需要被修改。修改的概率由 habitatData[i].immigration(当前栖息地的迁入率)决定。如果某个栖息地被选中参与迁移操作,则遍历它所有的坐标变量(SIV)。对于每一个坐标,同样基于迁入率随机判定是否需要修改。变量是否需要修改的概率同样由 habitatData[i].immigration(当前栖息地的迁入率)决定。

若某个坐标被选中进行修改,则需要确定从哪一个栖息地 “借用” 该坐标的参数值。该源栖息地采用轮盘赌选择法进行筛选,其被选中的概率与各个栖息地的迁出率 habitatData[j].emigration 成正比。也就是说,迁出率越高的栖息地,越有可能成为迁移操作的数据源。在概率计算过程中会做约束处理,不会将当前栖息地自身选为数据来源。一旦选定迁移源栖息地,就将源栖息地中对应坐标(栖息地适宜度变量 SIV)的参数值复制到当前栖息地。

最终,该方法在各个栖息地之间完成规范的特征信息(SIV)交换:物种数量少、迁入率高的栖息地,从物种丰富、迁出率高的栖息地获取特征信息。该机制可以让优质可行解的特征参数在整个种群中传播,同时保证当前最优解不被改动。

//+----------------------------------------------------------------------------+
//| Migration (exchange of SIVs between habitats)                              |
//+----------------------------------------------------------------------------+
void C_AO_BBO::Migration ()
{
  for (int i = 0; i < popSize; i++)
  {
    // Skip elite solutions
    if (i < elitismCount) continue;

    // Determine whether the habitat will be modified
    if (u.RNDprobab () < habitatData [i].immigration)
    {
      // For each coordinate (SIV)
      for (int c = 0; c < coords; c++)
      {
        // Determine whether this coordinate will be modified
        if (u.RNDprobab () < habitatData [i].immigration)
        {
          // Select a migration source based on emigration rates 
          double sumEmigration = 0.0;
          for (int j = 0; j < popSize; j++)
          {
            if (j != i) sumEmigration += habitatData [j].emigration;
          }

          if (sumEmigration > 0)
          {
            // Roulette source selection
            double roulette = u.RNDprobab () * sumEmigration;
            double cumSum = 0.0;

            for (int j = 0; j < popSize; j++)
            {
              if (j != i)
              {
                cumSum += habitatData [j].emigration;
                if (roulette <= cumSum)
                {
                  // Copy SIV from habitat j to habitat i
                  a [i].c [c] = a [j].c [c];
                  break;
                }
              }
            }
          }
        }
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

Mutation 方法用于对种群中的各个栖息地执行变异操作。变异的目的是对可行解引入随机改动,避免算法陷入局部最优,同时探索全新的搜索空间。

和迁移方法的规则一致,精英解(前elitismCount个栖息地)会被跳过,不执行变异操作。这样做是为了保留当前已经搜索到的最优解。针对其余每一个栖息地,都会计算对应的变异概率。关键点在于:变异概率与栖息地的生存概率(habitatData[i].probability)成 反比 。这也就意味着,生存概率较低的栖息地 —— 无论是性能极差的劣质解,还是性能极佳的优质极值解,都会拥有更高的变异概率,以此助力算法探索全新的区域。

如果生成的随机数小于计算得到的变异率,就会触发变异。从全部维度坐标中随机选取一个待变异的坐标变量(SIV)。在规定的取值区间内,为该选中的坐标生成一个全新的随机数值。随后调用 SeInDiSp 函数处理该新数值,将其约束在预设的合法范围内。

由此可见,变异方法为搜索过程引入了随机性,让算法能够挖掘出全新的、有潜力更优的可行解,尤其是在那些尚未被充分探索的搜索区域。算法依托栖息地生存概率动态调整变异率,以此平衡全局探索与局部利用两大搜索策略。

//+----------------------------------------------------------------------------+
//| Probability-based mutation                                                 |
//+----------------------------------------------------------------------------+
void C_AO_BBO::Mutation ()
{
  for (int i = 0; i < popSize; i++)
  {
    // Skip elite solutions
    if (i < elitismCount) continue;

    // The mutation rate is inversely proportional to the probability of existence
    double mutationRate = mutationProb * (1.0 - habitatData [i].probability);

    if (u.RNDprobab () < mutationRate)
    {
      // Select a random coordinate for mutation
      int mutateCoord = MathRand () % coords;

      // Generate a new value for the selected coordinate
      a [i].c [mutateCoord] = u.RNDfromCI (rangeMin [mutateCoord], rangeMax [mutateCoord]);
      a [i].c [mutateCoord] = u.SeInDiSp (a [i].c [mutateCoord],
                                          rangeMin [mutateCoord],
                                          rangeMax [mutateCoord],
                                          rangeStep [mutateCoord]);
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

CalculateProbability 方法会根据栖息地的物种数量,计算该栖息地的生存概率。该方法采用简化模型:当物种数量处于均衡值附近(取值区间中点)时,栖息地的生存概率达到最大值;一旦偏离该均衡值,概率会沿着高斯曲线快速下降。物种数量距离speciesMax/2越远,对应的生存概率就越低。

总的来说,该方法构建出这样一种模型:物种数量接近均衡值的栖息地,其生存概率要远高于物种数量严重偏离均衡值的栖息地。这是一种基于生物多样性、经过简化却十分高效的栖息地 “适宜度” 建模方式。

//+----------------------------------------------------------------------------+
//| Calculate the probability for a given number of species                    |
//+----------------------------------------------------------------------------+
double C_AO_BBO::CalculateProbability (int speciesCount)
{
  // Simplified probability model
  // Maximum probability in the middle of the range (equilibrium)
  int equilibrium = speciesMax / 2;
  double distance = MathAbs (speciesCount - equilibrium);
  double probability = MathExp (-distance * distance / (2.0 * equilibrium * equilibrium));

  return probability;
}
//——————————————————————————————————————————————————————————————————————————————


测试结果

经过对参数进行多组调试实验后,我发现基于生物地理学优化算法(BBO)能够取得较为出色的优化效果。

BBO|基于生物地理学优化算法|50.0|1.0|1.0|0.5|2.0|50.0|
=============================
5 Hilly's; Func runs: 10000; result: 0.9491244808033844
25 Hilly's; Func runs: 10000; result: 0.6945610309062928
500 Hilly's; Func runs: 10000; result: 0.35031241665471596
=============================
5 Forest's; Func runs: 10000; result: 0.9381951766964413
25 Forest's; Func runs: 10000; result: 0.6736501622157315
500 Forest's; Func runs: 10000; result: 0.2568167323109364
=============================
5 Megacity's; Func runs: 10000; result: 0.7461538461538464
25 Megacity's; Func runs: 10000; result: 0.4827692307692309
500 Megacity's; Func runs: 10000; result: 0.17369230769230892
=============================
综合总得分:5.26528 (58.50%)

可视化图表直观体现了 BBO 算法优异的优化效率。即便是难度最高的 Megacity 离散测试函数,该算法依旧表现出优秀的求解效果。

Hilly

Hilly函数上测试BBO

Forest

Forest函数上测试BBO

Megacity

Megacity函数上测试BBO

根据测试结果,这套性能出色的基于生物地理学优化算法(BBO)在算法性能排行榜中位列第 12 名,取得了靠前的名次。

# 算法 说明 Hilly Hilly
最终结果
Forest Forest
最终结果
Megacity (离散) Megacity
最终结果
最终
结果
% of
MAX
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 BBO 基于生物地理学的优化算法 0.94912 0.69456 0.35031 1.99399 0.93820 0.67365 0.25682 1.86867 0.74615 0.48277 0.17369 1.40261 5.265 58.50
13 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
14 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
15 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
16 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
17 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
18 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
19 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
20 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
21 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
22 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
23 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
24 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
25 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
26 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
27 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
28 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
29 (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
30 FBA 基于分形的算法 0.79000 0.65134 0.28965 1.73099 0.87158 0.56823 0.18877 1.62858 0.61077 0.46062 0.12398 1.19537 4.555 50.61
31 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
32 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
33 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
34 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
35 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
36 CAm 骆驼算法 M 0.78684 0.56042 0.35133 1.69859 0.82772 0.56041 0.24336 1.63149 0.64846 0.33092 0.13418 1.11356 4.444 49.37
37 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
38 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
39 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
40 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
41 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
42 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
43 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
44 CROm 珊瑚礁优化算法 M 0.78512 0.46032 0.25958 1.50502 0.86688 0.35297 0.16267 1.38252 0.63231 0.26738 0.10734 1.00703 3.895 43.27
45 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
RW 神经类群优化算法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


总结

基于生物地理学的优化算法(BBO)在各项测试中表现亮眼,在 45 种基于种群的优化算法中综合排名第 12 位,综合性能得分达 58.5%。对于这样一种依托简洁直观的自然隐喻设计而来的算法,该成绩十分优异。

尤其值得关注的是,BBO 能够高效处理中高维度优化问题,具备良好的可扩展性,还能有效应对众多优化算法普遍面临的 “维数灾难” 问题。

BBO 的核心理论基础 —— 岛屿间的物种迁徙,不仅是生动形象的自然类比,更是一种能够平衡搜索空间全局探索与已有解局部利用的高效机制。算法采用线性迁移模型:宜居度高的优质栖息地主动共享自身特征,宜居度差的劣质栖息地主动吸纳这些特征,信息会顺着天然梯度从优质解流向劣质解。

BBO 的变异算子极具特色,与传统算法的变异方式有着本质区别。该算法并未采用固定概率或随机概率的变异策略,而是依托理论模型,将变异概率设置为与栖息地生存概率成反比。这意味着最贴合自然规律、稳定性最强的中等质量解(物种数量适中)很少发生变异;而两类极端解,无论是最优解还是最差解,都会以更高频率产生变异。该策略形成了自适应调节机制,自动平衡种群的稳定性与多样性。

该算法在各类测试场景下稳定性优异:在所有测试中对应色阶表现较为一致,且与其他优化算法相比未出现明显的结果下滑

BBO 的一大突出优势是原理简洁且运行高效。部分现代元启发式算法需要调试大量参数、设计复杂算子,而 BBO 仅依托迁移、物种数量、栖息地适宜度这些通俗易懂的概念即可实现优化。

测试结果表明,BBO 并非又一款普通的仿生类算法,而是一套成熟且具备竞争力的优化方法,足以同该领域公认的顶尖算法同台竞技。兼具理论完备性、计算高效性与工程实用性,让 BBO 成为现代全局优化方法库中极具价值的一员。

tab

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

图表

图例 3. 算法测试结果直方图(比例从 0 到 100,越高越好,其中 100 是最大可能的理论结果,存档中有一个用于计算评级表的脚本)

BBO算法的优点和缺点:

优点:

  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_BBO.mq5
脚本 BBO 测试基准程序

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

附加的文件 |
BBO.zip (219.47 KB)
交易策略 交易策略
各种交易策略的分类都是任意的,下面这种分类强调从交易的基本概念上分类。
机器学习中的高斯过程:MQL5中的回归模型 机器学习中的高斯过程:MQL5中的回归模型
本文将介绍高斯过程(GP)这一概率机器学习模型的基础,并基于合成数据演示其在回归问题中的应用。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
市场模拟(第 19 部分):SQL 入门(二) 市场模拟(第 19 部分):SQL 入门(二)
正如我们在第一篇关于 SQL 的文章中所解释的那样,没有必要花费时间编写程序来执行 SQL 中已经内置的功能。然而,如果不了解基础知识,你就无法使用 SQL 或充分利用这个工具所提供的一切功能。因此,在本文中,我们将探讨如何在数据库中执行基本任务。