English Русский Español Português
preview
成功餐饮经营者算法(SRA)

成功餐饮经营者算法(SRA)

MetaTrader 5测试者 |
41 0
Andrey Dik
Andrey Dik

内容

  1. 概述
  2. 算法实现
  3. 测试结果


概述

我始终执着于优化问题与现实场景之间的共通性。在探索元启发式算法的新路径时,我发现群体优化与餐饮业演进存在相似之处——这一灵感最终催生了我提出的“成功餐饮经营者算法”(SRA)。

想象一位餐厅经营者,始终致力于优化菜单以提升人气、吸引新客。他并未彻底淘汰冷门菜品,而是采取更微妙的方式:找出最不受欢迎的菜品,再将其与最畅销菜品的元素巧妙融合。有时仅做保守调整,有时则大胆引入全新食材。目标始终如一:让最弱势的菜品蜕变为顾客的新宠。

这一烹饪隐喻正是SRA的核心。与传统进化算法直接淘汰劣质解不同,SRA通过将劣质解与优质元素配对,实现“劣解改造”。该方法在保持解空间多样性的同时,稳步提升种群的整体质量。

本文将阐述SRA的基本机制,分析其实现方式,并探讨“温度”和“烹饪实验强度”等参数如何调控“利用”与“探索”的平衡。我还会分享SRA在多种测试函数上与其他知名算法的对比基准结果。

这个始于创意思想实验的构想,已发展为具有独特优势的优化方法。诚邀您一同探索:这款受餐饮业启发的算法,如何以“独门配方”为优化问题提供解决方案。


算法实现

让我们通过简单的类比来理解算法的工作原理。假设我是一家餐厅的老板。我的菜单上有不同菜品,其中一些非常受欢迎,而另一些几乎从未被顾客点过。我会怎么做呢?我不会立即从菜单中移除冷门菜品(从而减少可选菜品的数量),而是会找出最不受欢迎的菜品并尝试改进它。那么如何改进?我会观察餐厅的畅销菜品,并借鉴其中的创意或食材。例如,我的鱼类菜品销量不佳,但沙拉却非常受欢迎。我会从成功的沙拉中提取元素(比如某种特色酱汁或摆盘方式),并将其添加到鱼类菜品中。最终,成为一道全新的菜品。

有时我会进行小幅调整,有时则会尝试大胆的革新。在餐厅开业初期,我会更多地进行实验;但当发现几道真正成功的菜品后,我开始精细调整食材的搭配和用量。随着时间的推移,即使是最弱势的菜品也会逐渐改进。甚至会出现这种情况:曾经的冷门菜品经过调整后,成为新的畅销菜!因此,餐厅的整体人气因所有菜品都获得成功而不断提升。

我的算法正是如此运作:不直接丢弃劣质解,而是通过借鉴优质解的创意不断改进它们。随着迭代的深入,实验的幅度逐渐减小,我们更多地对已有发现进行优化。图例1展示了算法的运行流程图。

SRA算法流程

图例1. RA算法操作流程图

流程图从初始化模块开始,生成初始菜单。随后进入算法主循环,其核心是当前按菜品质量排序的餐厅菜单。菜单以颜色渐变呈现:绿色(优质菜品)至红色(劣质菜品)。下方依次展示四个步骤:第一步,选择待改进菜品,根据二次分布概率,优先选取最差菜品和最优“供体”菜品;第二步,通过组合菜谱和变异食材(温度越高,实验越大胆)生成新变体;第三步,通过计算适应度函数值评估新菜品;第四步,降低温度,从而减少实验激进程度。左侧虚线箭头表示该过程持续迭代直至收敛或满足终止条件。右侧标注说明:A(绿色圆圈)— 最优菜品,B(红色圆圈)— 最差菜品。整个流程图直观呈现了一位餐饮经营者通过借鉴畅销菜品元素,系统性改进弱势菜品的优化过程。

接下来,让我们着手编写SRA算法的伪代码。

//初始化
生成包含popSize个智能体(菜单项)的种群
对于每个智能体:
在允许的范围内随机初始化所有坐标
设置初始温度 = 1.0
设置冷却系数 = 0.98
设置烹饪实验强度 = 0.3

//算法的主循环
直到满足停止条件:
// 步骤1:评估所有智能体
对于每个智能体:
计算适应度函数值
    
// 合并当前种群与历史种群
创建由当前智能体和历史智能体组成的综合菜单
按适应度函数值从优到劣排序综合菜单
    
// 步骤2:生成新解
对于新种群中的每个智能体:
// 从排序后种群前半部分选取最差智能体
复制索引为(popSize-1)的智能体坐标
        
// 选择改进或实验策略
如果 (随机数 < (1.0 - menuInnovationRate * 温度)):
// 我们使用二次轮盘赌法选择“供体”
r = 生成 [0,1] 随机数
            r = r²
donorIndex = 将r缩放至[0, popSize-1]范围
            
  // 对于每个坐标:
对于每个c坐标:
// 以80%的概率采用供体坐标
如果(随机数 < 0.8):
当前智能体.c = 供体.c
                
// 自适应变异
mutationRate = 0.1 + 0.4 * 温度 * (智能体索引 / popSize)
如果 (随机数 < mutationRate):
// 选择变异类型
如果(随机数 < 0.5):
当前智能体.c = 基于当前值的正态分布采样
否则:
当前个体.c = 范围内的随机值
                    
// 确保值在有效范围内
当前个体.c = 四舍五入至最接近的有效值
否则:
// 创建全新“菜品”
对于每个c坐标:
如果(随机数 < 0.7):
当前个体.c = 范围内的随机值
否则:
当前个体.c = 基于最优解的正态分布采样
                
// 确保值在有效范围内
当前个体.c = 四舍五入至最接近的有效值
        
// 精英策略 — 偶尔直接引入优质解特征
如果(随机数 < 0.1):
numEliteCoords = 生成 [1, 坐标数*0.3] 随机整数
对于i从1到numEliteCoords:
c = 随机坐标索引
当前个体.c = 最优解.c
    
// 步骤3:更新最优解
对于每个智能体:
如果智能体适应度 > 最优解适应度:
最优解 = 智能体
    
// 步骤4:降温处理
温度 = 温度 * 冷却系数
如果温度 < 0.1:
温度 = 0.1

返回最优解

现在我们可以开始编写算法代码了。编写一个继承自C_AO主类的C_AO_SRA类,用于实现SRA算法。让我们来详细了解一下。

构造函数与析构函数:popSize(种群规模)、temperature(初始温度)、coolingRate(冷却速率)、menuInnovationRate(菜单创新率)——这些参数决定了算法的主要特性,例如智能体数量及搜索过程的控制参数。

SetParams方法:根据"params"数组中存储的值更新类参数,这些参数需在构造函数中预先初始化。

Init方法:用于初始化算法。该方法接收参数的最小值、最大值、步长以及迭代次数,并准备算法执行搜索任务。

Moving与Revision方法:执行算法的核心操作,前者负责更新智能体的状态(如位置移动);后者负责参数的修订与自适应调整。

类成员:

  • temperature — 当前温度值,用于控制算法的搜索过程,并反映在算法的温度变化曲线中。
  • coolingRate — 冷却速率,用于控制温度下降的速度(即算法从探索阶段过渡到开发阶段的快慢)。
  • menuInnovationRate — 烹饪实验的强度,表示鼓励智能体探索新解(如全新菜品配方)的程度。
私有类成员:
  • S_AO_Agent menu [] — 智能体数组,在SRA算法中代表一个“菜单”(即当前候选解的集合)。
  • S_AO_Agent menuT [] — 临时智能体数组,用于存储备选菜品选项。
//——————————————————————————————————————————————————————————————————————————————
class C_AO_SRA : public C_AO
{
  public: //--------------------------------------------------------------------
  ~C_AO_SRA () { }
  C_AO_SRA ()
  {
    ao_name = "SRA";
    ao_desc = "Successful Restaurateur Algorithm (joo)";
    ao_link = "https://www.mql5.com/en/articles/17380";

    popSize            = 50;   // number of agents (size of the "menu")
    temperature        = 1.0;  // initial "temperature" for research control
    coolingRate        = 0.98; // cooling rate
    menuInnovationRate = 0.3;  // intensity of culinary experiments

    ArrayResize (params, 4);

    params [0].name = "popSize";            params [0].val = popSize;
    params [1].name = "temperature";        params [1].val = temperature;
    params [2].name = "coolingRate";        params [2].val = coolingRate;
    params [3].name = "menuInnovationRate"; params [3].val = menuInnovationRate;
  }

  void SetParams ()
  {
    popSize            = (int)params [0].val;
    temperature        = params      [1].val;
    coolingRate        = params      [2].val;
    menuInnovationRate = params      [3].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 temperature;        // current "temperature"
  double coolingRate;        // cooling rate 
  double menuInnovationRate; // intensity of culinary experiments

  private: //-------------------------------------------------------------------
  S_AO_Agent menu  [];
  S_AO_Agent menuT [];
};
//——————————————————————————————————————————————————————————————————————————————

C_AO_SRA类的Init方法用于初始化算法,具体步骤如下:

检查初始化:该方法调用StandardInit函数,传入参数范围的最小值、最大值及步长。若初始化失败,则返回"false"。

初始化数组:

  • 根据智能体数量,动态分配"menu"和"menuT"数组的容量。
  • 对"menu"数组中的每个智能体进行初始化。

温度重置: 将算法的初始温度"temperature"设置为"1.0"。

成功完成:当所有初始化步骤均成功执行,则返回"true"。

//——————————————————————————————————————————————————————————————————————————————
//--- Initialization
bool C_AO_SRA::Init (const double &rangeMinP  [],
                     const double &rangeMaxP  [],
                     const double &rangeStepP [],
                     const int epochsP = 0)
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;

  //----------------------------------------------------------------------------
  ArrayResize (menu,  popSize * 2);
  ArrayResize (menuT, popSize * 2);

  for (int p = 0; p < popSize * 2; p++) menu [p].Init (coords);

  temperature = 1.0; // reset temperature during initialization

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

使用C_AO_SRA类的Moving方法实现算法的主步骤。其功能分为两大模块:智能体初始化与通过变异和生成新解的适应性调整。

初始初始化(如果“revision”为“false”)
  • 每个智能体的初始化参数在给定范围 [rangeMin, rangeMax] 内按步长(rangeStep)随机生成,其值存储于智能体的"c"(当前解)和"cB"(备用解)中。
  • 将"revision"标识设置为"true",表示已生成初始解,方法终止。

降温操作:当前温度temperature乘以冷却系数(coolingRate),降低后续解变异的概率。

智能体主循环:对menu数组中的种群按适应度排序,选取前半部分中最差个体(即适应度最低的解)作为当前操作对象。

动作分类:根据当前温度动态调整行为策略,每个智能体:

  • 修改当前解:(从当前最优解中提取“供体配方”),进行非均匀变异。
  • 生成全新解:(随机值)。

精英保留:以一定的概率从历史最优解中选取部分元素,添加至新解中。

//——————————————————————————————————————————————————————————————————————————————
//--- The main step of the algorithm
void C_AO_SRA::Moving ()
{
  //----------------------------------------------------------------------------
  // Initial initialization
  if (!revision)
  {
    for (int p = 0; p < popSize; p++)
    {
      for (int c = 0; c < coords; c++)
      {
        a [p].c  [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
        a [p].c  [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
        a [p].cB [c] = a [p].c [c];
      }
    }

    revision = true;
    return;
  }

  //----------------------------------------------------------------------------
  // Lower the temperature
  temperature *= coolingRate;

  // Main loop on population agents
  for (int p = 0; p < popSize; p++)
  {
    // Take the worst element from the first half of the sorted population (with index popSize-1)
    // Remember that items are sorted from best to worst in the menu
    ArrayCopy (a [p].c, menu [popSize - 1].c, 0, 0, WHOLE_ARRAY);

    // Decide whether to create a hybrid or experiment with a new "dish"
    // The probability of an experiment depends on the temperature - there are more experiments at the beginning
    if (u.RNDprobab () < (1.0 - menuInnovationRate * temperature))
    {
      // Select a "donor-recipe" with a probability proportional to the success of the dish
      double r = u.RNDprobab ();
      r = pow (r, 2);                                         // Increased preference for better dishes
      int menuIND = (int)u.Scale (r, 0, 1.0, 0, popSize - 1); // The best ones are at the beginning of the array 

      // For each coordinate
      for (int c = 0; c < coords; c++)
      {
        // Take the parameter from a successful dish with the probability depending on the temperature
        if (u.RNDprobab () < 0.8)
        {
          a [p].c [c] = menu [menuIND].c [c];
        }

        // Mutation with adaptive probability - the further from the best solution and the higher the temperature, the more mutations
        double mutationRate = 0.1 + 0.4 * temperature * (double)(p) / popSize;
        if (u.RNDprobab () < mutationRate)
        {
          // Combination of different types of mutations
          if (u.RNDprobab () < 0.5) a [p].c [c] = u.GaussDistribution (a [p].c [c], rangeMin [c], rangeMax [c], 2);
          else                      a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); // Sometimes a completely new value

          // Make sure the value is within acceptable limits
          a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
        }
      }
    }
    else // Create a completely new "dish"
    {
      for (int c = 0; c < coords; c++)
      {
        // Variation 1: Completely random value
        if (u.RNDprobab () < 0.7)
        {
          a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
        }
        // Variation 2: based on the best solution found with a large deviation
        else
        {
          a [p].c [c] = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 1);
        }

        a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }

    // Sometimes we add elements from the best solution directly (elitism)
    if (u.RNDprobab () < 0.1)
    {
      int numEliteCoords = u.RNDintInRange (1, coords / 3); // Take from 1 to 30% of the coordinates
      for (int i = 0; i < numEliteCoords; i++)
      {
        int c = u.RNDminusOne (coords);
        a [p].c [c] = cB [c]; // Take the value from the best solution
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

C_AO_SRA类的Revision方法负责更新最优解并管理算法运行期间的解集合(“menu”)

寻找最优智能体::检查当前所有智能体的适应度值(f),通过比较选出适应度最高者。如果发现新最优智能体,则更新全局最优适应度值fB,并记录其索引bestIND。

更新全局最优解:当存在更优解(即bestIND不等于-1)时,将最优智能体的决策参数c复制到cB(全局最优解存储变量)中。

更新解集合(“menu”):将当前所有智能体的参数添加到全局解集合"menu"中,形成完整的实验记录库。

解集合排序:对"menu"数组中的解根据适应度从高到低排序,确保最优解位于数组前半部分。这样便于算法后续迭代。

温度控制:如果当前温度低于预设阈值"0.1",则强制将其重置为0.1,避免算法过早收敛。
//——————————————————————————————————————————————————————————————————————————————
//--- Update the best solution taking into account greedy selection and the probability of making worse decisions
void C_AO_SRA::Revision ()
{
  int bestIND = -1;

  // Find the best agent in the current population
  for (int p = 0; p < popSize; p++)
  {
    if (a [p].f > fB)
    {
      fB = a [p].f;
      bestIND = p;
    }
  }

  // If we find a better solution, update cB
  if (bestIND != -1) ArrayCopy (cB, a [bestIND].c, 0, 0, WHOLE_ARRAY);

  // Add the current set of dishes to the general "menu"
  for (int p = 0; p < popSize; p++)
  {
    menu [popSize + p] = a [p];
  }

  // Sort the entire "menu" from best to worst solutions
  // After sorting, the first half of the menu will contain the best solutions,
  // which will be used in the next iteration
  u.Sorting (menu, menuT, popSize * 2);

  // Prevent the temperature from falling below a certain threshold
  if (temperature < 0.1) temperature = 0.1;
}
//——————————————————————————————————————————————————————————————————————————————


测试结果

现在,让我们看一下SRA算法的工作成果。测试结果如下:

SRA|Successful Restaurateur Algorithm|50.0|1.0|0.98|0.3|
=============================
5 Hilly's; Func runs: 10000; result: 0.9688326305968623
25 Hilly's; Func runs: 10000; result: 0.6345483084017249
500 Hilly's; Func runs: 10000; result: 0.292167027537253
=============================
5 Forest's; Func runs: 10000; result: 0.946368863880973
25 Forest's; Func runs: 10000; result: 0.5550607959254661
500 Forest's; Func runs: 10000; result: 0.19124225531141872
=============================
5 Megacity's; Func runs: 10000; result: 0.7492307692307693
25 Megacity's; Func runs: 10000; result: 0.4403076923076923
500 Megacity's; Func runs: 10000; result: 0.12526153846153956
=============================
总分:4.90302 (54.48%)

可视化SRA算法在测试平台上的运行结果,以便我们能够总结其搜索策略的特征。在此情况下,我们观察到其广泛的空间探索能力:智能体在整个空间中均匀分布,甚至能覆盖到最偏远的区域。同时,在局部极值处无明显的聚集迹象;其移动轨迹呈现出明显的随机性(看似混沌)。

尽管算法具备优秀的全局探索能力,但在优化解的精细调整方面存在缺陷,导致最终收敛精度相对较低。请注意,多次实验的测试结果存在小幅差异。

Hilly值

SRA在Hilly测试函数上

Forest值

SRAForest测试函数上

Megacity值

SRA在Megacity测试函数上

基于测试结果,该算法在最强群体优化算法排行榜中位列第20名。目前,排行榜中收录了9种专有优化算法(JOO),其中包括新的SRA算法。

# AO 描述 Hilly值 Hilly最终值 Forest值 Forest最终值 Megacity (离散) Megacity最终值 最终结果 最大百分比
10 p (5 F) 50 p (25 F) 1000 p (500 F) 10 p (5 F) 50 p (25 F) 1000 p (500 F) 10 p (5 F) 50 p (25 F) 1000 p (500 F)
1 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 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
43 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
44 MEC 思维进化计算 0.69533 0.53376 0.32661 1.55569 0.72464 0.33036 0.07198 1.12698 0.52500 0.22000 0.04198 0.78698 3.470 38.55
45 CSA 圆搜索算法 0.66560 0.45317 0.29126 1.41003 0.68797 0.41397 0.20525 1.30719 0.37538 0.23631 0.10646 0.71815 3.435 38.17
RW 随机游走 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


总结

在开发并测试了SRA后,我可以自信地说,已经证明了SRA的成功。目前,该算法在排行榜中位列第20名——对于一个全新概念而言,这一成绩已相当可观。在分析结果时,我注意到其运行存在一些特殊现象。针对低维问题,测试结果呈现分散性。尤其在离散的Megacity函数中表现尤为显著。该函数对算法极具挑战性,陷入局部极值是常态而非例外。

针对高维问题,SRA的表现略低于预期。这可能是由于在高维空间中,改进最差解的策略需要对温度和冷却速率参数进行更精细的调优。

尽管如此,我认为SRA是一个具有潜力的优质算法。其“餐饮隐喻”不仅使算法逻辑易于理解,还为直观改进开辟了道路,例如优化自适应变异机制,或尝试不同的“招牌菜”(donor dishes)选择方案。

在开发SRA时,我的目标并非超越现有优化方法,而是通过原创的生活化隐喻揭示新的概念水平。研究结果有力证明,这一方法值得在元启发式算法生态中占据一席之地。

聚焦种群中最差解并将其作为实验基础——这一乍看疯狂的理念,却意外地展现出强大生产力。正是这种“逆袭者重塑”原则,释放了惊人的优化潜力。如同技艺精湛的餐饮经营者将冷门菜品改造成未来爆款,SRA利用领先解的“食材”,将弱势解转化为优质解。

这一实践印证了科研中的一条宝贵法则:即使是最非传统的理念,只要实现得当,也能带来实际价值。非常规方法往往能揭示传统范式下被忽视的问题本质。

标签

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

图表

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

SRA的优缺点:

优点:

  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_SRA.mq5
脚本 SRA测试

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

附加的文件 |
SRA.zip (173.8 KB)
从 MQL5 向 Discord 发送消息,创建 Discord-MetaTrader 5 机器人 从 MQL5 向 Discord 发送消息,创建 Discord-MetaTrader 5 机器人
与 Telegram 类似,Discord 可以使用其通信 API 以 JSON 格式接收信息和消息。在本文中,我们将探讨如何使用 Discord API 将 MetaTrader 5 的交易信号和更新发送到您的 Discord 交易社区。
从新手到专家:使用 MQL5 制作动画新闻标题(二) 从新手到专家:使用 MQL5 制作动画新闻标题(二)
今天,我们又向前迈进了一步,整合了一个外部新闻 API 作为我们的 News Headline EA 的头条新闻来源。在这个阶段,我们将探索各种新闻来源 —— 包括成熟的和新兴的 —— 并学习如何有效地访问它们的 API。我们还将介绍如何将检索到的数据解析成适合在我们的 EA 交易中显示的格式。加入讨论,我们将探索直接在图表上访问新闻标题和经济日历的好处,所有这些都在一个紧凑、不干扰用户的界面中。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
交易中的神经网络:二维连接空间模型(Chimera) 交易中的神经网络:二维连接空间模型(Chimera)
本文将探讨创新的 Chimera 框架:利用神经网络分析多元时间序列的二维状态空间模型。该方法具有高精度和低计算成本,优于传统方式和变换器架构。