English Русский Español Deutsch 日本語 Português
preview
确定性振荡搜索(DOS)

确定性振荡搜索(DOS)

MetaTrader 5交易 |
38 0
Andrey Dik
Andrey Dik

内容

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


引言

优化算法在不断发展,旨在克服传统方法的根本性局限。大多数元启发式优化算法高度依赖随机过程与随机数。尽管这类方法在避免局部最优解上表现出色,但其非确定性特性,在需要结果精确可复现的领域会带来问题。

本文介绍确定性振荡搜索(DOS)—— 这是一种新型元启发式算法,它结合了传统基于梯度方法的优势与群体算法的高效性,同时完全不使用随机数。

DOS由Archana于2017年提出,用于求解复杂的全局优化问题。其核心思想是:在搜索空间中模拟粒子的振荡运动,并采用确定性初始位置分布。该算法的关键特点是能够处理高维问题,同时保持完全可复现性:在相同初始条件下,算法每次运行都能得到完全一致的结果。

与大多数元启发式算法不同,DOS引入了“适应度斜率”概念。通过这一机制,粒子可以判断当前移动方向是否在提升解的质量,并自适应调整搜索策略。粒子可处于三种斜率状态之一:正向(移动使解更优)、负向(移动使解变差)、未知。

该信息用于控制粒子的振荡行为。传统梯度法一旦到达所有方向都会使目标函数变差的位置,就会停止搜索。而DOS通过群体机制突破了这一限制:当振荡运动无法带来改进时,群体机制便会启动。此时,粒子会朝着当前已知的全局最优解的方向移动。

本文将详细阐述DOS算法的数学基础,分析其特性与实现要点,并通过若干测试问题验证其优化效率。 


算法实现

现在,让我们来研究DOS算法的工作原理。它不采用随机游走,而是基于几条简单规则的系统性搜索,完全不依赖随机性。算法首先将若干个“探索者”(粒子)放置在搜索空间中的不同位置。这些位置并非随机,而是由特定公式确定,以实现对区域的均匀覆盖。每个探索者都有初始方向和移动速度。当探索者向前移动时,它会记录周围地形是变高(更优)还是变低(更差)。我们称之为“斜率” —— 这是一种简单判断是否在朝正确方向前进的方式。

下面进入算法的关键环节。当一个探索者发现自己不再上升、反而开始下降(适应度变差)时,它不会直接停下或原路返回。相反,它会进行一次“反弹” —— 掉头向相反方向继续移动,但速度减半。就像网球撞到墙壁后反弹,只是能量减弱。

这种反弹形成了振荡运动,算法也因此得名。每一次反弹,探索者都会更精确地逼近极值点。但如果探索者陷入了局部陷阱 —— 比如一座小山丘,周围全是更低的区域,这时DOS会启用另一套机制。如果探索者尝试各个方向,发现全都是下坡,它就会切换到另一种模式 —— “群集机制”。在此模式下,它会朝着所有探索者目前找到的最优点移动。

与随机搜索或试错法不同,DOS利用改进方向信息和全体探索者的集体经验,系统性地探索解空间。同时,它不需要复杂的导数计算,也不需要存储大量搜索历史。因此,通过移动、反弹、聚集这几条简单规则,DOS便能逐步为复杂问题找到最优解。

下图展示了该算法的以下关键特征:一个包含全局最优与多个局部最优的二维搜索空间(以等高线表示),以及从起点到全局最优的路径,体现出DOS算法特有的行为:

  • 粒子确定性的初始位置,
  • 搜索空间中的振荡(锯齿形)运动,
  • 向全局最优的自适应移动

算法的核心组件包括:确定性粒子初始化、适应度斜率概念、振荡运动以及群体机制(向已知最优解移动)。
斜率状态可以是:

  • 正向(+1):当前移动使适应度提升,
  • 负向(-1):当前移动使适应度下降,
  • 未知(0):初始化阶段或策略切换后的状态。

DOS算法

图例1. 算法运行过程

上图清晰地展示了DOS如何结合传统梯度法(通过振荡进行局部搜索)与群体算法的优势,同时保持完全确定性的运行特性。在了解运行原理之后,让我们接下来开始编写算法的伪代码。

步骤1:初始化准备

  • 创建数组,用于存储每个粒子的位置、速度、上一代适应度值和斜率状态
  • 将当前找到的最优解初始化为最小适应度值

步骤2:确定性粒子初始化

  • 对于每个粒子:
    • 通过确定性公式在搜索空间中定位,确保均匀覆盖
    • 将初始速度设为0
    • 将初始斜率状态设置为“未知”(0)
    • 将上一代适应度值设为最小可能值

步骤3:主优化循环

  • 重复执行,直到达到最大迭代次数:第一部分:粒子移动
    • 对于每个粒子:
      • 将当前适应度值保存为上一代适应度值
      • 通过叠加当前速度更新粒子位置
      • 如果新位置超出搜索边界,将其限制在合理范围内
    第二部分:评估与调整运动
    • 对于每个粒子:
      • 计算新的适应度值
      • 如果新适应度优于当前最优解,则更新最优解
      • 情况1:斜率状态为“未知”(0)
        • 如果新适应度更优,则将斜率设置为“正向”(1)
        • 如果新适应度更差,则将斜率设置为“负向”(-1)
        • 如果适应度无变化,则保持斜率为“未知”。
      • 情况2:斜率状态为“正向”(1)
        • 如果新适应度变差:
          • 将运动方向反转
          • 速度减半
          • 将斜率设置为“负向”(-1)
      • 情况3:斜率状态为“负向”(-1)
        • 如果新适应度变差:
          • 启用群体机制:在当前速度上叠加指向最优解的向量(乘以移动系数)
          • 将斜率设置为“未知 ”(0)
      • 检查速度是否为0或接近0:
        • 如果速度几乎为0:
          • 将速度设置为指向最优解的方向(乘以移动系数)
          • 将斜率设置为“未知 ”(0)

步骤4:结束

  • 返回找到的最优解及其适应度值

现在我们可以开始编写DOS算法代码。首先创建一个结构体,用于存储优化过程中粒子的状态。该结构体包含这些字段:速度斜率状态(正向、负向、未知)和各维度速度分量数组,这样可以方便地存储和处理粒子的运动参数。

为初始化该结构体,提供一个方法:将斜率设置为默认值,并且创建指定大小的速度数组,全部填充为0,确保算法启动前的初始状态正确。

此外,还实现了零速度检测方法:检查所有速度分量,如果在指定精度内全部接近0,返回"true",否则返回"false"。该方法用于判断粒子是否已达到稳定状态,还是需要继续移动。

// Structure for storing particle velocity
struct S_DOS_Velocity
{
    int    slope; // Particle slope (-1: negative, 0: unknown, 1: positive)
    double v [];  // Velocity components for each dimension


    void Init (int dims)
    {
      slope = 0;
      ArrayResize     (v, dims);
      ArrayInitialize (v, 0.0); // Quick initialization of the entire array to zeros
    }

    // Check for zero velocity
    bool IsZero (double epsilon = 1e-10)
    {
      for (int i = 0; i < ArraySize (v); i++) if (MathAbs (v [i]) > epsilon) return false;
      return true;
    }
};

//——————————————————————————————————————————————————————————————————————————————

C_AO_DOS类代表本算法的具体实现。该类继承自基类C_AO的通用功能,并额外添加了DOS算法专属逻辑。该类的主要特性:构造函数初始化默认参数,包括种群大小、向最优解移动的系数,并创建参数数组。SetParams()方法用设置并校验参数(如种群大小popSize和移动系数movementFactor),确保符合约束条件。Init()方法负责初始化所有前置条件:搜索区间、变化步长以及迭代次数。

粒子运动逻辑(方法):
  • Moving()实现粒子在搜索空间中的基础移动机制,基于当前速度与评估值运行。
  • Revision()用于在每一步迭代后调整粒子的位置或速度。

类内部定义了S_DOS_Velocity速度结构体,用于存储每个粒子在所有维度上的速度分量,并包含初始化与零速度检测的方法。

内部辅助方法:
  • InitializeParticles()作为粒子初始化的辅助函数,ProcessParticleMovement()作为粒子位置更新的辅助函数。二者共同实现算法的核心逻辑。

    整体而言,该类以结构化方式实现了DOS算法,通过粒子的位置、速度与搜索方向,系统性地引导解空间的搜索过程。

    //——————————————————————————————————————————————————————————————————————————————
    class C_AO_DOS : public C_AO
    {
      public: //--------------------------------------------------------------------
      ~C_AO_DOS () { }
      C_AO_DOS ()
      {
        ao_name = "DOS";
        ao_desc = "Deterministic Oscillatory Search";
        ao_link = "https://www.mql5.com/en/articles/18154";
    
        // Set default parameters
        popSize        = 30;   // population size
        movementFactor = 0.95; // movement factor towards the best solution
    
        // Create and initialize the parameters array
        ArrayResize (params, 2);
        params [0].name = "Population Size"; params [0].val = popSize;
        params [1].name = "Movement Factor"; params [1].val = movementFactor;
      }
    
      void SetParams ()
      {
        // Set parameter values with validation
        popSize        = (int)MathMax (5, params [0].val);             // Minimum 5 particles for efficiency
        movementFactor = MathMax (0.1, MathMin (1.0, params [1].val)); // Limit from 0.1 to 1.0
      }
    
      bool Init (const double &rangeMinP  [],  // minimum values
                 const double &rangeMaxP  [],  // maximum values
                 const double &rangeStepP [],  // step change
                 const int     epochsP = 0);
    
      void Moving   ();
      void Revision ();
    
      //----------------------------------------------------------------------------
      double movementFactor;          // movement factor towards the best solution
    
      S_DOS_Velocity velocities [];  // Array of particle velocity structures
    
      private: //-------------------------------------------------------------------
      void InitializeParticles     ();
      void ProcessParticleMovement (int particleIndex);
    };
    //——————————————————————————————————————————————————————————————————————————————
    

    Init方法负责为算法执行做好初始化准备。首先,它调用基类初始化方法,完成算法运行所需的初始搜索区间与步长设置。基础初始化成功后,为数组分配内存,用于存储所有粒子的速度信息。

    针对种群中的每个粒子,初始化各维度的速度数组,为后续运动过程建立初始状态。最后,调用方法以确定性方式将粒子放置到初始位置,明确它们在搜索空间中的起始点。

    该方法的结果:生成一组具备完整初始条件的粒子种群,准备就绪,可开始迭代搜索过程。

    //——————————————————————————————————————————————————————————————————————————————
    bool C_AO_DOS::Init (const double &rangeMinP  [],  // minimum values
                         const double &rangeMaxP  [],  // maximum values
                         const double &rangeStepP [],  // step change
                         const int     epochsP = 0)    // number of epochs
    {
      // Standard C_AO initialization
      if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
    
      //----------------------------------------------------------------------------
      // Allocating memory for arrays
      ArrayResize (velocities, popSize);
    
      // Initialize the velocities for each dimension
      for (int i = 0; i < popSize; i++) velocities [i].Init (coords);
    
      // Initialize particle positions deterministically
      InitializeParticles ();
    
      return true;
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    Moving方法实现DOS算法中粒子在搜索空间内的移动逻辑,并按顺序处理种群中的每一个粒子(从第一个到最后一个)。对于每个粒子,先保存其当前适应度函数值"f"。这一步是为了后续对比,判断粒子位置是更优还是变差。

    针对粒子的每一个坐标(维度),通过将当前坐标加上对应速度分量计算出新的坐标值。新坐标会根据步长限制在设定的区间rangeMin[d]和rangeMax[d]内,确保粒子不会超出允许的搜索范围。 

    最终,Moving方法完成粒子在搜索空间中的位置更新,保留上一状态信息,并在约束与离散化条件下,确保新坐标的有效性。 

    //+----------------------------------------------------------------------------+
    //| Basic method of particle movement                                          |
    //+----------------------------------------------------------------------------+
    void C_AO_DOS::Moving ()
    {
      // Handle all particles
      for (int i = 0; i < popSize; i++)
      {
        // Save the fitness value
        a [i].fP = a [i].f;
    
        // Calculate new coordinates based on velocity
        for (int d = 0; d < coords; d++)
        {
          // Update position
          a [i].c [d] += velocities [i].v [d];
    
          // Round to the nearest acceptable step
          a [i].c [d] = u.SeInDiSp (a [i].c [d], rangeMin [d], rangeMax [d], rangeStep [d]);
        }
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    Revision方法负责更新最优解信息,并在搜索过程中处理粒子的运动调整。该方法会依次处理种群中的所有粒子。对于每个粒子,都会检查其当前解是否优于全局最优适应度值fB。如果满足,则更新全局最优值,并保存对应的最优坐标。针对每个粒子,会调用一个独立的方法,根据适应度函数的变化重新计算并调整其位置与速度。

    该方法的运行结果:完成最优解更新,并让系统准备好进入下一阶段搜索,使粒子能够基于最新信息继续移动。

    //+----------------------------------------------------------------------------+
    //| Fitness function update method                                             |
    //+----------------------------------------------------------------------------+
    void C_AO_DOS::Revision ()
    {
      // Handle each particle
      for (int i = 0; i < popSize; i++)
      {
        // Update the best solution if the current solution is better
        if (a [i].f > fB)
        {
          fB = a [i].f;
          ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY);
        }
    
        // Handle particle motion based on fitness change
        ProcessParticleMovement (i);
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    

    ProcessParticleMovement方法负责根据适应度函数变化与当前方向,调整单个粒子在搜索空间中的运动状态。如果粒子索引无效,则方法直接终止。为加速访问,系统会缓存粒子的当前适应度、上一代适应度值以及当前运动斜率。算法会根据当前与历史适应度差值以及当前斜率,决定粒子下一步的移动方向,规则如下:

    • 如果斜率未知,则根据适应度变化重新确定方向(正向、负向或保持未知);
    • 如果斜率原本为正向但适应度变差,则将斜率切换为负向,并将所有轴上的速度减半,促使粒子改变运动方向;
    • 如果斜率原本为负向且适应度持续变差,则触发“群集机制” —— 粒子向全局最优解方向移动,各轴速度朝最优解方向递增。

    如果所有方向的速度均为0,则根据当前坐标与全局最优解坐标的差值(结合移动系数)设置速度,启动向全局最优解的移动。最终,系统会根据实时状态调整速度的方向与大小,使粒子对适应度变化做出合理响应,并“学习”向最优方向移动。

    该方法的最终目标:为粒子提供动态自适应运动,同时结合局部解与全局解的变化,实现高效的最优值搜索。

    //+----------------------------------------------------------------------------+
    //| Handle particle motion after fitness update                                |
    //+----------------------------------------------------------------------------+
    void C_AO_DOS::ProcessParticleMovement (int particleIndex)
    {
      // Local variables for access optimization
      double currentFitness  = a [particleIndex].f;
      double previousFitness = a [particleIndex].fP;
      int    currentSlope    = velocities [particleIndex].slope;
    
      // Comparison of fitnesses to determine the movement direction
      double fitnessDiff = currentFitness - previousFitness;
    
      // Handle a slope according to the current state
      if (currentSlope == 0) // Unknown slope
      {
        // Determine the slope based on the change in fitness
        velocities [particleIndex].slope = (fitnessDiff > 0) ? 1 : (fitnessDiff < 0) ? -1 : 0;
      }
      else
        if (currentSlope == 1 && fitnessDiff < 0) // Positive slope and deterioration of fitness
        {
          // Change direction and decrease velocity
          for (int d = 0; d < coords; d++) velocities [particleIndex].v [d] *= -0.5; // Optimized form of division by 2
    
          velocities [particleIndex].slope  = -1; // Change the slope to negative
        }
        else
          if (currentSlope == -1 && fitnessDiff < 0) // Negative slope and fitness degradation
          {
            // Apply the swarming mechanism - movement towards the global optimum
            for (int d = 0; d < coords; d++) velocities [particleIndex].v [d] += (cB [d] - a [particleIndex].c [d]) * movementFactor;
    
            velocities [particleIndex].slope = 0; // Reset the slope as unknown
          }
    
      // Check for zero velocity using the structure method
      if (velocities [particleIndex].IsZero ())
      {
        // Initialize the velocity by moving towards the global optimum
        for (int d = 0; d < coords; d++) velocities [particleIndex].v [d] = (cB [d] - a [particleIndex].c [d]) * movementFactor;
    
        // Reset the slope
        velocities [particleIndex].slope  = 0;
      }
    }
    //——————————————————————————————————————————————————————————————————————————————
    


    测试结果

    现在,让我们来看一下结果。可见,这款内置群体效应的梯度型算法,在处理优化任务时,表现优于传统的常规梯度法。

    DOS|Deterministic Oscillatory Search Algorithm|50.0|0.95|
    =============================
    5 Hilly's; Func runs: 10000; result: 0.3422040822277234
    25 Hilly's; Func runs: 10000; result: 0.3421751631202356
    500 Hilly's; Func runs: 10000; result: 0.3421605659711745
    =============================
    5 Forest's; Func runs: 10000; result: 0.5708601371368296
    25 Forest's; Func runs: 10000; result: 0.34628707444514434
    500 Forest's; Func runs: 10000; result: 0.32879379664917996
    =============================
    5 Megacity's; Func runs: 10000; result: 0.19999999999999998
    25 Megacity's; Func runs: 10000; result: 0.20923076923076928
    500 Megacity's; Func runs: 10000; result: 0.23076923076922945
    =============================
    总分: 2.91248 (32.36%)

    可视化结果显示,在低维函数上,算法的结果存在较大离散性。 

    Hilly值

    DOS在Hilly测试函数上

    Forest值

    DOSForest测试函数上

    Megacity值

    DOSMegacity测试函数上

    在种群优化算法的评级表中,DOS算法仅作为参考示例列出。

    # 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 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
    30 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
    31 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
    32 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
    33 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
    34 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
    35 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
    36 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
    37 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
    38 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
    39 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
    40 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
    41 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
    42 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
    43 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
    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 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
    DOS 确定性振荡搜索 0.34220 0.34218 0.34216 1.02654 0.57086 0.34629 0.32879 1.24594 0.20000 0.20923 0.23077 0.64000 2.912 32.36
    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


    总结

    算法所需配置的参数极少(仅种群大小和移动系数),这简化了实际应用,并降低了参数设置不当的风险。

    其三态斜率机制(正向、负向、未知)允许粒子根据当前搜索方向的质量自适应调整行为,这正是该算法的核心创新点。算法不涉及复杂数学运算,因此计算效率很高。 

    其主要优势在于将群体算法的高效性与确定性方法的稳定性、可复现性相结合,尽管总体上确定性算法略逊于随机算法,但在解决某些特定问题时,此类方法依然具备实用价值。

    标签

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

    图表

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

    DOS的优缺点:

    优点:

    1. 快速。
    2. 实现简单。

    缺点:

    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_DOS.mq5
    脚本 DOS测试

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

    附加的文件 |
    DOS.zip (215.67 KB)
    你应该了解的 MQL5 向导技巧(第67部分):使用 TRIX 和威廉百分比范围的形态 你应该了解的 MQL5 向导技巧(第67部分):使用 TRIX 和威廉百分比范围的形态
    三重指数平滑摆动指标(TRIX)与威廉百分比指标,是另一组可在 MQL5 智能交易系统(EA)中搭配使用的技术指标。和我们此前介绍的指标组合一样,这组指标同样具备互补性:TRIX 用于判断趋势,威廉百分比指标则确认支撑位与阻力位。按照惯例,我们借助 MQL5 向导,测试这两个指标组合的实战可行性。
    您应该了解的MQL5向导技巧(第六十六部分):结合点积核使用FrAMA与强力指数形态 您应该了解的MQL5向导技巧(第六十六部分):结合点积核使用FrAMA与强力指数形态
    分形自适应移动平均线(FrAMA)指标与强力指数震荡指标分别属于趋势类和成交量类工具,两者搭配使用可用于开发智能交易系统(EA)。本文承接前一篇对该指标组合的介绍,进一步探讨如何将机器学习应用到该组合中。我们将使用一种搭载点积核的卷积神经网络,并以这两个指标的数据作为输入进行预测。相关实现封装在一个自定义信号类文件中,可配合MQL5向导直接生成EA。
    神经网络在交易中的应用:多元时间序列的双重聚类(终篇) 神经网络在交易中的应用:多元时间序列的双重聚类(终篇)
    我们继续实现 DUET 框架作者提出的方法,该框架提供了一种创新的时间序列分析方法,结合时间和通道聚类来揭示分析数据中的隐藏模式。
    神经网络在交易中的应用:多元时间序列的双重聚类(DUET) 神经网络在交易中的应用:多元时间序列的双重聚类(DUET)
    DUET 框架提供了一种创新的时间序列分析方法,该方法结合了时间和通道聚类,以揭示分析数据中的隐藏模式。这使得模型能够随着时间的推移而适应变化,并通过消除噪声来提高预测质量。