Discusión sobre el artículo "Métodos de optimización de la biblioteca ALGLIB (Parte II)" - página 2

 

Busca en la función skin del artículo usando el método lbfgs.




No he entendido de qué mil parámetros estamos hablando. Si usted tiene un ejemplo de tal función, por favor compartirlo.

 

No sé de qué Skin estamos hablando, pero la función original Skin test y varias otras fueron desarrolladas por @Andrey Dik en este hilo en 2010 y desde aproximadamente 2020 se puede encontrar y ver la fórmula aquí \MQL5\Experts\Examples\Math 3D\Functions.mqh y aquí \MT5\MQL5\Experts\Examples\Math 3D Morpher\Functions.mqh. Se trata de una función interesante, pero simple. Más tarde desarrolló otros benchmarks como Hilly, Forest y Megacity.

En cuanto a las pruebas con funciones bidimensionales, y más aún unidimensionales, se ha dicho anteriormente que no tiene sentido práctico, ya que la mayoría de los AOs las resuelven de forma elemental, incluso los algos más simples con random (hay PRNGs superrápidos) mostrarán resultados sorprendentemente altos, creando una ilusión de alta eficiencia y velocidad. Por lo tanto, se consideran dimensiones de 10 y superiores. El aumento de la dimensionalidad puede lograrse duplicando benchmarks unidimensionales o bidimensionales (la suma obtenida se divide por el número de funciones de prueba), de modo que el mínimo y el máximo de la función de prueba se conozcan siempre independientemente de la dimensionalidad. Se trata de una técnica habitual para aumentar la dimensionalidad y seguir conociendo de forma fiable el área de definición de la función de prueba.

Sobre "igualar". Vale, igualemos, pero no les hará sentirse mejor. La mayoría de los AO de población se sienten bien con un tamaño de población de 50 (algunos más pequeños, por ejemplo 10, algunos más grandes, por ejemplo 100), si limitamos el número de ejecuciones de FF a 10 000 épocas, consideramos épocas = 10 000 / tamaño de población, obtenemos 10 000 / 50 = 200. Por lo tanto, sólo tenemos que ejecutar 50 veces los métodos de gradiente con diferente posición inicial en el espacio y tomar la mejor solución de ellos, simulando así la población. Y así repetirlo varias veces y calcular la media de estos mejores valores. De esta forma habrá una completa "igualdad de condiciones", sólo que si antes los métodos tenían posibilidad de encontrar una solución en 10.000 iteraciones, ahora habrá 200 iteraciones pero 50 intentos.

Veamos que sacamos de esto. Arreglemos el script de este artículo para que L-BGFS simule la población.

int epochCount = NumbTestFuncRuns_P / PopSize_P;

  for (int test = 0; test < NumberRepetTest_P; test++)
  {
    double bestInPop = -DBL_MAX; // el mejor de la población

    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;

Y obtenemos estos resultados:

LBFGS|método BFGS de memoria limitada para optimización a gran escala|0.9|
=============================
5 Hilly's; Func runs: 10000; resultado: 0.52942166492675
25 Hilly's; Func runs: 10000; resultado: 0.30437018399902754
500 Hilly's; Func runs: 10000; resultado: 0.253457675831117
=============================
5 Forest's; Func runs: 10000; resultado: 0.46775770774270276
25 Forest's; Func runs: 10000; resultado: 0.20030246823425313
500 Bosques; Func ejecuta: 10000; resultado: 0.15436391164477226
=============================
5 Megaciudades; Func ejecuta: 10000; resultado: 0.3046153846153846
25 Megaciudades; Func ejecuta: 10000; resultado: 0.13384615384615386
500 Megaciudades; Func ejecuta: 10000; resultado: 0.09492307692307773
=============================
Puntuación total: 2.44306 (27.15%)

El 27,15% es aproximadamente el puesto 42 de la clasificación actual, de un total de 45 puestos.

Ahora todo el mundo está en igualdad de condiciones.

Adjunto al post es la secuencia de comandos para esta prueba. Todas las inclusiones necesarias se pueden encontrar en el archivo al artículo.

Archivos adjuntos:
 
Maxim Dmitrievsky #:

Busca en la piel ph-i del artículo usando el método lbfgs.

No he entendido de qué mil parámetros estamos hablando. Si usted tiene un ejemplo de una función de este tipo, por favor compartirlo.

Es el mismo que en el artículo. Tomado de la terminal. Dice que es de las más complicadas. Luego dice que es muy sencilla.

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

No está claro que subpersonalidad tomar en serio.

¿Dónde puedo encontrar el código de una función compleja para 1000 parámetros?

 
Maxim Dmitrievsky #:
Igual que en el artículo. Tomado de la terminal. Dice que es uno de los más complicados. Luego dice que es muy sencillo.

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

No está claro qué subpersonalidad tomar en serio.

¿Dónde puedo encontrar el código de una función compleja para 1000 parámetros?

Lee con más atención, Hilly se desarrolló más tarde y es más compleja que Skin. Skin pertenece al grupo de las simples (como Rastrigin y la mayoría de las otras famosas), porque el 50% de la superficie es exactamente el 50% en altura. Todo está dicho en los artículos.

Todas las fuentes necesarias están en el archivo del artículo, estúdialo.

¿Dónde está escrito que es "muy" simple?
 
Andrey Dik #:

Lee con más atención, Hilly se desarrolló más tarde y es más complejo que Skin. Skin pertenece al grupo de los simples (como Rastrigin y la mayoría de los otros famosos) ya que el 50% de la superficie se encuentra exactamente al 50% en altura. Todo dicho en los artículos.

Todas las fuentes necesarias están en el archivo del artículo, estúdialo.

Compruebo en python, sólo necesito el código de la función, que es complejo.

Yo uso MQL sólo en el nivel de apertura-cierre de operaciones.
 
Maxim Dmitrievsky #:

Compruebo en python, sólo necesito el código de una función que es compleja.

Yo uso MQL sólo a nivel de apertura-cierre de operaciones.

Tome el código Hilly del artículo, ejecutarlo a través de chat, será un código de python.

O Megacity, es una función muy compleja para cualquier AO.

 
Andrey Dik #:

Toma el código Hilly del artículo, ejecútalo a través del chat, será código python.

O Megacity, es muy complejo para cualquier función de AO.

Y C_dimentional o como se llame, donde conseguirlo, para tener muchos parametros.

 
Maxim Dmitrievsky #:

Y C_dimentional o lo que sea, ¿de dónde lo sacas? Para tener muchos parámetros.

Aquí hay un fresco (el artículo lo tiene en el archivo) clase de función de prueba del núcleo:

double CalcFunc (double &args []) //argumentos de la función
  {
    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 ();

      //doble u = 0,5;
      //x = x * cos (u) - y * sen (u);
      //y = x * sen (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;
  }

Simplemente lanza un array multidimensional (quiero decir - en una dimensión del array hay muchas celdas, espacio multidimensional) de cualquier dimensionalidad en args, el método dispersará los argumentos del array a funciones bidimensionales. Está claro que si lanzas un array con dimensionalidad impar, una celda será descartada y no participará en los cálculos. Es decir, se trata de una función de prueba multidimensional con un número par de dimensiones.

Más adelante la lanzaré en base a unidimensionales, será más práctica y se podrán construir gráficos más claros.

El código comentado es la capacidad de rotar la función por algún ángulo. Esto es un quebradero de cabeza para muchos AOs. Todavía no se utiliza en ninguna parte.

 
Sería bueno añadir al punto de referencia el tiempo para el que el algoritmo resuelve el problema. A mí, por ejemplo, me interesa el tiempo en primer lugar.
 
Evgeniy Chernish #:
Sería bueno añadir al punto de referencia el tiempo para el que el algoritmo resuelve el problema. A mí, por ejemplo, me interesa el tiempo en primer lugar.
Gracias, consideraré esta posibilidad.