文章 "ALGLIB 库优化方法(第二部分)" - 页 2

 

使用 lbfgs 方法搜索文章中的皮肤函数。




我不明白我们所说的千参数是什么。如果您有此类函数的示例,请与我们分享。

 

我不知道我们说的是哪个皮肤,但是最初的皮肤测试函数和其他几个函数是由@Andrey Dik 在 2010 年的这个主题 中开发的,从 2020 年左右开始,你可以在这里 (MQL5\Experts\Examples\Math 3D\Functions.mqh )和这里 (MT5\MQL5\Experts\Examples\Math 3D Morpher\Functions.mqh )找到并查看公式。这是一个有趣的函数,但很简单。后来,他又开发了其他基准,如丘陵、森林和大城市。

至于二维函数的测试,一维函数的测试就更不用说了,上面说过这没有实际意义,因为大多数 AO 解决这些问题都是初级的,即使是最简单的随机算法(有超快的 PRNG)也会显示出令人惊讶的高结果,造成一种高效率和高速度的假象。因此,我们考虑使用 10 维或更高的维数。增加维度可以通过复制一维基准或二维基准来实现(获得的总和除以测试函数的数量),这样无论维度如何,测试函数的最小值和最大值总是已知的。这是一种常用的技术,可以在提高维度的同时仍然可靠地知道测试函数的定义区域。

关于 "均衡"。好吧,让我们把它等同起来,但这不会让他们感觉更好。大多数种群 AO 在种群规模为 50 时感觉良好(有些较小,如 10,有些较大,如 100),如果我们将 FF 运行次数限制为 10 000 个历时,我们认为历时 = 10 000 / 种群规模,则得到 10 000 / 50 = 200。因此,我们只需运行50 次 梯度法,并在空间中设置不同的初始位置,从中提取最佳解,从而模拟种群。如此重复多次,并计算这些最佳值的平均值。这样就可以实现完全的 "条件相等",只不过以前的方法有机会在 10000 次迭代中找到一个解,而现在只有200 次迭代 和 50 次尝试。

让我们看看会有什么结果。让我们修复本文中的 L-BGFS 脚本来模拟种群。

int epochCount = NumbTestFuncRuns_P / PopSize_P;

  for (int test = 0; test < NumberRepetTest_P; test++)
  {
    double bestInPop = -DBL_MAX; // 人口中的佼佼者

    for (int p = 0; p < PopSize_P; p++)
    {
      for (int i = 0; i < funcCount; i++)
      {
        x [i * 2] = Ut.RNDfromCI (bndl [i * 2], bndu [i * 2]);
        x [i * 2 + 1] = Ut.RNDfromCI (bndl [i * 2 + 1], bndu [i * 2 + 1]);
      }

      //------------------------------------------------------------------------
      C_OptimizedFunction  fFunc; fFunc.Init (params, epochCount, PopSize_P, clrConv);
      CObject              obj;
      CNDimensional_Rep    frep;
      CMinLBFGSReportShell rep;

      double epsg = 1 e-16;
      double epsf = 1 e-16;

      CAlglib::MinLBFGSCreateF  (1, x, DiffStep_P, fFunc.state);
      CAlglib::MinLBFGSSetCond  (fFunc.state, epsg, epsf, ArgumentStep_P, epochCount);
      CAlglib::MinLBFGSSetScale (fFunc.state, s);
      CAlglib::MinLBFGSOptimize (fFunc.state, fFunc, frep, 0, obj);
      CAlglib::MinLBFGSResults  (fFunc.state, x, rep);
      //------------------------------------------------------------------------

      if (fFunc.fB > bestInPop) bestInPop = fFunc.fB;
    }

    aveResult += bestInPop;
  }

  aveResult /= NumberRepetTest_P;

结果如下

LBFGS|limited memory BFGS method for large scale optimization|0.9|
=============================
5 Hilly's; Func runs: 10000; result: 0.52942166492675
25 Hilly's; Func runs: 10000; result: 0.30437018399902754
500 Hilly's; Func runs: 10000; result: 0.253457675831117
=============================
5 Forest's; Func runs: 10000; result: 0.46775770774270276
25 Forest's; Func runs: 10000; result: 0.20030246823425313
500 Forest's; Func runs: 10000; result: 0.15436391164477226
=============================
5 Megacity's; Func runs: 10000; result: 0.3046153846153846
25 Megacity's; Func runs: 10000; result: 0.13384615384615386
500 Megacity's; Func runs: 10000; result: 0.09492307692307773
=============================
全部得分:2.44306 (27.15%)

27.15% 在目前的 45 个排名中约排在第 42 位。

现在大家都处于公平竞争的环境中。

本帖的附件是本次测试的脚本。所有必要的内容均可在文章的存档中找到。

附加的文件:
 
Maxim Dmitrievsky #:

使用 lbfgs 方法搜索文章中的皮肤 ph-i。

我不明白我们所说的千参数是什么。如果您有这样的函数示例,请与我们分享。

和文章中的一样。取自终端。它说这是最复杂的函数之一。然后又说非常简单。

https://www.mql5.com/ru/forum/118887/page2#comment_3150124

不知道该认真对待哪个子人格。

在哪里可以找到 1000 个参数的复杂函数的代码?

 
Maxim Dmitrievsky #:
与文章中相同。摘自航站楼。上面说这是最复杂的系统之一。然后又说非常简单

https:// www.mql5.com/ru/forum/118887/page2#comment_3150124

不知道该认真对待哪个子人格。

在哪里可以找到 1000 个参数的复杂函数的代码?

请仔细阅读,Hilly 是后来开发的,它比 Skin 更复杂。Skin 属于简单函数(如 Rastrigin 和其他大多数著名函数),因为 50%的表面高度正好是 50%。文章中已经说得很清楚了。

所有必要的资料都在文章的档案中,请仔细研究。

哪里说它 "非常 "简单了?
 
Andrey Dik #:

请仔细阅读,Hilly 是后来开发的,它比 Skin 更复杂。皮肤 "属于简单组(如 Rastrigin 和其他大多数著名的皮肤),因为其表面的 50%正好位于高度的 50%。所有这些都可以在文章中找到。

所有必要的资料都在文章的档案中,请研究一下。

我用 python 检查,我只需要函数的代码,这很复杂。

我只在开仓-平仓交易层面使用 MQL。
 
Maxim Dmitrievsky #:

我用 python 检查,我只是需要一个复杂函数的代码。

我只在开仓-平仓交易层面使用 MQL。

从文章中提取 Hilly 代码,通过聊天运行,它将成为 python 代码。

或者 Megacity,它对于任何 AO 都是一个非常复杂的函数。

 
Andrey Dik #:

将文章中的 Hilly 代码在聊天工具中运行,它将成为 python 代码。

或 Megacity,对于任何 AO 功能来说都非常复杂。

还有 C_dimentional,不管它叫什么名字,从哪里可以得到它? 要有很多参数

 
Maxim Dmitrievsky #:

还有 C_dimentional,不管它是什么,你从哪里得到的? 要有很多参数。

这里有一个全新的(文章存档中有)核心测试函数类:

double CalcFunc (double &args []) //函数参数
  {
    int numbOfFunctions = ArraySize (args) / 2;
    if (numbOfFunctions < 1) return GetMinFunValue ();

    double x, y;
    double sum = 0.0;
    for (int i = 0; i < numbOfFunctions; i++)
    {
      x = args [i * 2];
      y = args [i * 2 + 1];

      if (!MathIsValidNumber (x)) return GetMinFunValue ();
      if (!MathIsValidNumber (y)) return GetMinFunValue ();

      //double u = 0.5;
      //x = x * cos (u) - y * sin (u);
      //y = x * sin (u) + y * cos (u);

      if (x < GetMinRangeX ()) return GetMinFunValue ();
      if (x > GetMaxRangeX ()) return GetMinFunValue ();

      if (y < GetMinRangeY ()) return GetMinFunValue ();
      if (y > GetMaxRangeY ()) return GetMinFunValue ();

      sum += Core (x, y);
    }
    
    sum /= numbOfFunctions;

    return sum;
  }

只需将一个任意维度的多维数组(我的意思是--在数组的一个维度上有许多单元格,多维空间)抛入 args,该方法就会将数组中的参数分散到二维函数中。很明显,如果你抛出一个奇数维度的数组,其中一个单元格将被丢弃,不会参与计算。也就是说,这是一个具有偶数维数的多维测试函数。

我稍后会在一维的基础上发布它,这样会更实用,也可以更清晰地构建图表。

注释代码是将函数旋转一定角度的功能。这对许多 AO 来说是个难题。目前还没有在任何地方使用。

 
最好能在基准中增加算法解决问题的时间。例如,我首先对时间感兴趣。
 
Evgeniy Chernish #:
最好能在基准中增加算法解决问题的时间。例如,我首先对时间感兴趣。
谢谢,我会考虑这种可能性的。