English Русский 中文 Deutsch 日本語 Português 한국어 Français Italiano Türkçe
preview
Algoritmos de optimización de la población: Algoritmo de murciélago (Bat algorithm - BA)

Algoritmos de optimización de la población: Algoritmo de murciélago (Bat algorithm - BA)

MetaTrader 5Ejemplos | 13 abril 2023, 15:57
706 0
Andrey Dik
Andrey Dik

Contenido:

1. Introducción
2. Descripción del algoritmo
3. Resultados de las pruebas


1. Introducción

Los murciélagos son animales asombrosos, los científicos creen que los primeros murciélagos aparecieron hace unos 65-100 millones de años, al mismo tiempo que los dinosaurios. Entre todos los mamíferos, solo los murciélagos poseen alas. Existen más de 1300 especies de murciélagos, y se pueden encontrar en casi todas partes, salvo en las regiones polares. Durante el día se ocultan en refugios. Para navegar en cuevas oscuras y cazar después del anochecer, los murciélagos confían en la ecolocalización, un sistema que les permite detectar objetos usando ondas sonoras, es decir, se ecolocalizan emitiendo un sonido de alta frecuencia que se propaga hasta que golpea un objeto y se refleja en este. La ecolocalización es una especie de sónar: el murciélago (el pequeño murciélago común) emite un sonido fuerte y de pulsos cortos. Cuando el sonido llega a un objeto, el eco regresa a sus oídos después de un corto periodo de tiempo: así se orientan los murciélagos en el espacio y determinan la posición de su presa. 

El algoritmo de murciélago (BA) es un algoritmo heurístico introducido por Yang en 2010 que imita el comportamiento de ecolocalización de los murciélagos para realizar una optimización global. Las metaheurísticas, generalmente inspiradas en la naturaleza y los procesos físicos, ahora se usan como una de las técnicas más poderosas para resolver muchos problemas complejos de optimización. La optimización consiste en seleccionar los mejores elementos para un determinado conjunto de criterios a partir de una serie de opciones eficientes, lo cual muestra muchas ventajas y desventajas diferentes en cuanto a la eficiencia computacional y la probabilidad de optimización global.

La optimización de funciones ofrece un marco formal para modelar y resolver una serie de problemas específicos, ofreciendo una función "objetivo" que toma un parámetro como entrada. El objetivo consiste en encontrar el valor del parámetro combinado para devolver el mejor valor. Este marco resulta lo suficientemente abstracto como para que varios problemas puedan interpretarse como problemas de "optimización de funciones".


No obstante, la optimización de funciones tradicional se usa solo para resolver algunos problemas pequeños, que a menudo no son aplicables en la práctica. Por consiguiente, los científicos están redirigiendo su atención hacia la naturaleza, que ofrece modelos ricos para resolver estos problemas. Usando el modelado de sistemas biológicos naturales, se han propuesto muchos algoritmos de optimización de enjambres inteligentes para resolver problemas aplicados utilizando métodos no tradicionales. Dichos algoritmos son ampliamente utilizados en diversos problemas de optimización debido a su excelente desempeño. El BA es un nuevo y moderno algoritmo similar a un enjambre que realiza un proceso de búsqueda usando murciélagos artificiales como agentes de búsqueda, y simulando el volumen del pulso sonoro natural y la frecuencia de emisión de los murciélagos reales.


2. Descripción del algoritmo

En el algoritmo de murciélago básico, cada murciélago se trata como una partícula "sin masa ni tamaño" que representa una solución válida en el espacio de soluciones. Para diferentes funciones de aptitud, cada murciélago tiene un valor de característica correspondiente y determina el individuo óptimo actual comparando los valores de característica. A continuación, se actualiza la frecuencia de la onda sonora, la velocidad, la velocidad de emisión de impulsos y el volumen de cada murciélago en la población. Luego continúa la evolución iterativa, se aproxima y se genera la solución óptima actual, obteniéndose finalmente la solución óptima global. El algoritmo actualiza la frecuencia, la velocidad y la posición de cada murciélago.

Para el algoritmo estándar, se requieren cinco parámetros básicos: frecuencia, volumen, ondulación y coeficientes de volumen y ondulación. La frecuencia se usa para equilibrar el impacto de la mejor posición histórica en la posición actual. Un individuo murciélago buscará lejos de la posición histórica del grupo cuando el rango de frecuencia de búsqueda sea grande, y al contrario.

Existen bastantes parámetros del algoritmo en comparación con otros considerados anteriormente:

input double MIN_FREQ_P          = 0.0;
input double MAX_FREQ_P         = 1.0;
input double MIN_LOUDNESS_P  = 0.0;
input double MAX_LOUDNESS_P = 1.5;
input double MIN_PULSE_P        = 0.0;
input double MAX_PULSE_P        = 1.0;
input double ALPHA_P               = 0.3;
input double GAMMA_P              = 0.3;

Al escribir el algoritmo BA, nos encontramos con que, en muchas fuentes, los autores de los artículos describen el algoritmo de formas completamente distintas: las diferencias se daban tanto en el uso de los términos en la descripción de puntos clave como en las características algorítmicas fundamentales, así que lo describiremos según nuestro propio entendimiento. Los principios físicos básicos que subyacen a la ecolocalización se pueden aplicar en el algoritmo con importantes reservas y convenciones. Vamos a suponer que los ratones usan pulsos sonoros con una frecuencia que va desde MinFreq a MaxFreq. La frecuencia afecta la velocidad de movimiento del ratón en el espacio. También se usa el concepto condicional de sonoridad, que afecta la transición del estado de búsqueda local en la ubicación de la posición actual del murciélago al estado global en la vecindad de la mejor solución. La frecuencia de ondulación aumenta a lo largo de la optimización, mientras que el volumen de los sonidos disminuye.

Pseudocódigo del algoritmo BA (Figura 1):

1. Inicialización de la población de murciélagos.
2. Generación de la frecuencia, la velocidad y las nuevas soluciones.
3. Búsqueda de una solución local.
4. Actualización de una solución global.
5. Disminución del volumen y aumento de la frecuencia de pulsación.
6. Repetiremos el paso 2 hasta que se cumpla el criterio de parada.

scheme

Figura 1. Esquema de bloques del algoritmo BA.

Empezaremos por describir el código. Para describir el agente de búsqueda "murciélago", necesitaremos una estructura en la que detallar todas las características necesarias para describir al completo el estado en el momento de cada iteración. El array position [] se usa para almacenar las mejores coordenadas de posición en el espacio, mientras que el array auxPosition [] se usa para las coordenadas "operativas" actuales. Necesitamos el array speed [] en el cálculo del vector de velocidad por coordenadas. frecuency es la frecuencia de los pulsos sonoros, initPulseRate es la frecuencia de pulso inicial (individual para cada murciélago desde el comienzo de la optimización). pulseRate es la frecuencia de pulso en la iteración actual. loudness es el volumen de los pulsos sonoros. fitness es el valor de la función de aptitud después del último movimiento. fitnessBest es el mejor valor de la función de aptitud del agente para todas las iteraciones. 

//——————————————————————————————————————————————————————————————————————————————
struct S_Bat
{
  double position    [];
  double auxPosition [];
  double speed       [];
  double frequency;
  double initPulseRate;
  double pulseRate;
  double loudness;
  double fitness;
  double fitnessBest;
};
//——————————————————————————————————————————————————————————————————————————————

La clase de algoritmo de murciélago incluye un array de estructuras de agentes de búsqueda, así como los límites y los pasos del espacio explorado, las mejores coordenadas encontradas por el algoritmo, el mejor valor de la función de aptitud y las constantes para almacenar los parámetros del algoritmo, además de un método de inicialización público, dos métodos públicos necesarios para operar con el algoritmo y los métodos privados específicos del algoritmo.

//——————————————————————————————————————————————————————————————————————————————
class C_AO_BA
{
  //============================================================================
  public: S_Bat  bats      []; //bats
  public: double rangeMax  []; //maximum search range
  public: double rangeMin  []; //manimum search range
  public: double rangeStep []; //step search
  public: double cB        []; //best coordinates
  public: double fB;           //FF of the best coordinates

  public: void Init (const int    paramsP,
                     const int    batsNumberP,
                     const double min_FREQ_P,
                     const double max_FREQ_P,
                     const double min_LOUDNESS_P,
                     const double max_LOUDNESS_P,
                     const double min_PULSE_P,
                     const double max_PULSE_P,
                     const double alpha_P,
                     const double gamma_P,
                     const int    maxIterP);

  public: void Flight (int epoch);
  public: void Preparation ();

  //============================================================================
  private: void Walk               (S_Bat &bat);
  private: void AproxBest          (S_Bat &bat, double averageLoudness);
  private: void AcceptNewSolutions (S_Bat &bat);
  private: int  currentIteration;
  private: int  maxIter;

  private: double MIN_FREQ;
  private: double MAX_FREQ;

  private: double MIN_LOUDNESS;
  private: double MAX_LOUDNESS;

  private: double MIN_PULSE;
  private: double MAX_PULSE;

  private: double ALPHA;
  private: double GAMMA;

  private: int    params;
  private: int    batsNumber;

  private: bool   firstFlight;

  private: double SeInDiSp  (double In, double inMin, double inMax, double step);
  private: double RNDfromCI (double min, double max);
  private: double Scale     (double In, double InMIN, double InMAX, double OutMIN, double OutMAX,  bool revers);
};
//——————————————————————————————————————————————————————————————————————————————

En el método público Init () asignaremos los valores de los parámetros de la superestructura del algoritmo a las constantes internas, asignaremos la memoria para los arrays, restableceremos la variable al valor mínimo para almacenar el mejor ajuste y restableceremos la bandera de la iteración inicial . En general, este método no resulta complicado y es algo especial.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BA::Init (const int    paramsP,
                    const int    batsNumberP,
                    const double min_FREQ_P,
                    const double max_FREQ_P,
                    const double min_LOUDNESS_P,
                    const double max_LOUDNESS_P,
                    const double min_PULSE_P,
                    const double max_PULSE_P,
                    const double alpha_P,
                    const double gamma_P,
                    const int    maxIterP)
{
  MathSrand (GetTickCount ());

  fB = -DBL_MAX;

  params       = paramsP;
  batsNumber   = batsNumberP;
  MIN_FREQ     = min_FREQ_P;
  MAX_FREQ     = max_FREQ_P;
  MIN_LOUDNESS = min_LOUDNESS_P;
  MAX_LOUDNESS = max_LOUDNESS_P;
  MIN_PULSE    = min_PULSE_P;
  MAX_PULSE    = max_PULSE_P;
  ALPHA        = alpha_P;
  GAMMA        = gamma_P;
  maxIter      = maxIterP;

  ArrayResize (rangeMax,  params);
  ArrayResize (rangeMin,  params);
  ArrayResize (rangeStep, params);

  firstFlight = false;

  ArrayResize (bats, batsNumber);

  for (int i = 0; i < batsNumber; i++)
  {
    ArrayResize (bats [i].position,    params);
    ArrayResize (bats [i].auxPosition, params);
    ArrayResize (bats [i].speed,       params);

    bats [i].fitness  = -DBL_MAX;
  }

  ArrayResize (cB, params);
}
//——————————————————————————————————————————————————————————————————————————————

El primer método llamado en cada iteración es Flight(). Este concentra el marco principal de la lógica de búsqueda, mientras que el resto de los detalles se colocan en métodos privados auxiliares específicos de este algoritmo de optimización. En la primera iteración, restableceremos la bandera firstFlight (el restablecimiento tiene lugar durante la inicialización en el método Init ()).  Esto significa que deberemos asignar un estado inicial a cada murciélago, que supondrá una posición aleatoria en el espacio de búsqueda:

  • valor cero de la velocidad,
  • frecuencia individual de pulsos sonoros, asignada según un número aleatorio en el rango especificado por los parámetros,
  • frecuencia de la pulsación individual inicial, también dada por un número aleatorio en el rango de parámetros,
  • volumen de los pulsos sonoros en el rango de parámetros.

Como podemos ver, todos los murciélagos artificiales son individuales, cada uno tiene un conjunto individual de características de señales sonoras, lo cual los hace más parecidos a los murciélagos reales en la naturaleza. En toda la población, que puede constar de varios cientos de miles de individuos, la madre puede encontrar una sola cría por la firma de sonido única que emite su vástago.

Si establecemos la bandera firstFlight, deberemos realizar operaciones básicas para desplazar los murciélagos. Una de las características interesantes del algoritmo es que se usa el concepto de volumen sonoro promedio de toda la población; en general, el volumen sonoro disminuye a lo largo del coeficiente alfa a través de todas las iteraciones. Hay dos tipos de movimientos de murciélagos aquí: Walk () - movimiento individual con el cálculo del vector de velocidad para cada componente de las coordenadas y el movimiento local en la vecindad de la mejor solución.

Con cada siguiente iteración, la intensidad de las pulsaciones disminuirá, lo cual influirá en la intensidad del estudio del entorno. Por lo tanto, el estudio y la explotación cambiarán dinámicamente a lo largo de la optimización. A continuación, veremos cómo la iteración actual afecta al comportamiento de los murciélagos.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BA::Flight (int epoch)
{
  currentIteration = epoch;

  //============================================================================
  if (!firstFlight)
  {
    fB = -DBL_MAX;

    //--------------------------------------------------------------------------
    for (int b = 0; b < batsNumber; b++)
    {
      for (int p = 0; p < params; p++)
      {
        bats [b].position    [p] = RNDfromCI (rangeMin [p], rangeMax [p]);
        bats [b].position    [p] = SeInDiSp (bats [b].position [p], rangeMin [p], rangeMax [p], rangeStep [p]);
        bats [b].auxPosition [p] = bats [b].position    [p];
        bats [b].speed       [p] = 0.0;
        bats [b].frequency       = RNDfromCI (MIN_FREQ, MAX_FREQ);
        bats [b].initPulseRate   = RNDfromCI (MIN_PULSE, MAX_PULSE / 2);
        bats [b].pulseRate       = bats [b].initPulseRate;
        bats [b].loudness        = RNDfromCI (MAX_LOUDNESS / 2, MAX_LOUDNESS);
        bats [b].fitness         = -DBL_MAX;
        bats [b].fitnessBest     = -DBL_MAX;
      }
    }

    firstFlight = true;
  }
  //============================================================================
  else
  {
    double avgLoudness = 0;

    for (int b = 0; b < batsNumber; b++)
    {
      avgLoudness += bats [b].loudness;
    }

    avgLoudness /= batsNumber;

    for (int b = 0; b < batsNumber; b++)
    {
      Walk (bats [b]);

      if (RNDfromCI (MIN_PULSE, MAX_PULSE) > bats [b].pulseRate)
      {
        AproxBest (bats [b], avgLoudness);
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

El segundo método público obligatorio llamado en cada iteración, Preparation (), se requiere para actualizar la mejor solución global. Aquí podemos ver cómo se usa el concepto de "volumen". Dado que con cada iteración el volumen de cada ratón disminuirá a lo largo de un coeficiente (parámetro de ajuste del algoritmo "alfa"), la probabilidad de un estudio local disminuirá junto con la intensidad del estudio de la solución global. Es decir, la probabilidad de actualizar la mejor posición de cada murciélago disminuirá con cada iteración. Este es uno de esos momentos en el algoritmo que resulta menos comprensible, al menos en nuestro caso, sin embargo, el autor del algoritmo implementó esto, lo cual significa que es necesario.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BA::Preparation ()
{
  //----------------------------------------------------------------------------
  for (int b = 0; b < batsNumber; b++)
  {
    if (bats [b].fitness > fB)
    {
      fB = bats [b].fitness;
      ArrayCopy (cB, bats [b].auxPosition, 0, 0, WHOLE_ARRAY);
    }
  }

  //----------------------------------------------------------------------------
  for (int b = 0; b < batsNumber; b++)
  {
    if (RNDfromCI (MIN_LOUDNESS, MAX_LOUDNESS) < bats [b].loudness && bats [b].fitness >= bats [b].fitnessBest)
    {
      AcceptNewSolutions (bats [b]);
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

El método privado Walk() garantiza que cada murciélago se mueva individualmente en relación con su mejor posición actual hasta el momento, dada la mejor solución global. Este método usa la frecuencia de los pulsos sonoros, que varía aleatoriamente en el rango [MIN_FREQ;MAX_FREQ]. La frecuencia es necesaria para calcular la velocidad de movimiento del agente de búsqueda, que es el producto de la frecuencia y la diferencia entre la mejor posición del murciélago y la mejor solución global. Después de eso, el valor de la velocidad se añadirá vector por vector a la mejor solución actual del murciélago. Por lo tanto, trabajaremos con cantidades físicas desproporcionadas, pero qué podemos hacer: esto es solo una aproximación a los objetos físicos reales. La plausibilidad en este caso deberá ser despreciada. Tras calcular la nueva posición, las coordenadas deberán verificarse fuera de rango usando el método SeInDiSp ().

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BA::Walk (S_Bat &bat)
{
  for (int j = 0; j < params; ++j)
  {
    bat.frequency       = MIN_FREQ + (MAX_FREQ - MIN_FREQ) * RNDfromCI (0.0, 1.0);
    bat.speed       [j] = bat.speed [j] + (bat.position [j] - cB [j]) * bat.frequency;
    bat.auxPosition [j] = bat.position [j] + bat.speed [j];

    bat.auxPosition [j] = SeInDiSp (bat.auxPosition [j], rangeMin [j], rangeMax [j], rangeStep [j]);
  }
}
//——————————————————————————————————————————————————————————————————————————————

El segundo método privado, AproxBest(), se encarga de desplazar los murciélagos en relación con la mejor solución global, ofreciendo una mejora adicional de las coordenadas. Resulta casi imposible comprender el significado físico de esta acción, que consiste en la suma vector a vector de las coordenadas del incremento como sonoridad media entre toda la población de murciélagos multiplicada por un número aleatorio en el rango [-1.0; 1.0]. Hemos intentado reducir los valores a la dimensionalidad de la función optimizada a través del vector de valores válidos del área de definición, pero los resultados de la prueba han resultado ser peores que en la versión del algoritmo del autor, así que hemos dejado todo como está. No obstante, a nuestro juicio, la eficiencia del algoritmo BA se puede mejorar, aunque requiera cierta investigación adicional, que no es el objetivo en este caso. Después de calcular las coordenadas, verificaremos que los valores superen el rango permitido utilizando el método SeInDiSp ().

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BA::AproxBest (S_Bat &bat, double averageLoudness)
{
  for (int j = 0; j < params; ++j)
  {
    bat.auxPosition [j] = cB [j] + averageLoudness * RNDfromCI (-1.0, 1.0);
    bat.auxPosition [j] = SeInDiSp (bat.auxPosition [j], rangeMin [j], rangeMax [j], rangeStep [j]);
  }
}
//——————————————————————————————————————————————————————————————————————————————

Otro método privado específico es AcceptNewSolutions (), que llamaremos cuando se cumpla la condición de comprobación para la frecuencia de pulsación de los pulsos sonoros para cada murciélago. Aquí se aceptará la nueva mejor solución individual, y también se recalcularán el volumen individual y la frecuencia de pulsación individual. Aquí podremos ver cómo el número ordinal de iteraciones está involucrado en el cálculo de la frecuencia de pulsación.

En este punto de la lógica del algoritmo, nos hemos permitido algunas libertades y hemos modificado la lógica, haciendo que el resultado fuera independiente de la dimensionalidad del número total de iteraciones, lo que finalmente ha incrementado ligeramente la eficiencia del algoritmo. En la versión original del autor, el número de iteración estaba directamente involucrado en la fórmula no lineal para calcular la frecuencia del pulso, en BA ya hay muchas convenciones, y en este caso no podíamos cerrar los ojos a una más.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_BA::AcceptNewSolutions (S_Bat &bat)
{
  ArrayCopy(bat.position, bat.auxPosition, 0, 0, WHOLE_ARRAY);
  bat.fitnessBest = bat.fitness;
  bat.loudness    = ALPHA * bat.loudness;
  double iter     = Scale (currentIteration, 1, maxIter, 0.0, 10.0, false);
  bat.pulseRate   = bat.initPulseRate *(1.0 - exp(-GAMMA * iter));
}
//——————————————————————————————————————————————————————————————————————————————

La dependencia de la frecuencia de pulsación respecto al número de la iteración actual (x en el gráfico) y el parámetro de configuración GAMMA se muestran en la figura 2.

gamma

Figura 2. Dependencia de la frecuencia de pulsación respecto al número de la iteración actual y el parámetro de configuración GAMMA con valores de 0,9, 0,7, 0,5, 0,3, 0,2.

3. Resultados de las pruebas

En el último artículo, mencionamos nuestros planes de revisar la metodología para calcular la calificación de los algoritmos probados. En primer lugar, como la mayoría de los algoritmos pueden afrontar fácilmente las funciones de prueba de dos variables y la diferencia entre los resultados es casi indistinguible, hemos decidido aumentar el número de variables para las dos primeras pruebas en todas las funciones de prueba. Ahora el número de variables será 10, 50 y 1000.

En segundo lugar, hemos reemplazado la función de prueba Skin con la función Rastrigin, ampliamente utilizada (figura 3). Esta función es igual de suave que Skin, tiene una superficie compleja con muchos extremos locales, un máximo global en cuatro puntos y un mínimo global en el centro de los ejes de coordenadas.

En tercer lugar, hemos decidido normalizar los resultados de la prueba a un rango de valores entre todos los algoritmos de la tabla, donde el mejor resultado será 1.0 y el peor resultado será 0.0. Esto nos permitirá evaluar uniformemente los resultados de la prueba, mientras que la complejidad de las funciones se considerará según los resultados de cada uno de los algoritmos de optimización en las pruebas.

Después de ello, los resultados de las pruebas de los algoritmos se sumarán, al resultado máximo se le asignará un valor de 100 (resultado máximo de referencia), mientras que el valor mínimo será 1. Esto nos permitirá comparar directamente los algoritmos entre sí de manera uniforme teniendo en cuenta la complejidad de las funciones de prueba. Ahora los resultados impresos en Print () se guardarán en los archivos fuente de los scripts de prueba para cada algoritmo, respectivamente, mientras que el script que calcula las puntuaciones en las pruebas se adjuntará al artículo en el archivo y se actualizará en artículos posteriores con la adición de los resultados de los nuevos algoritmos en consideración.



rastrigin

Figura 3. Función de prueba de Rastrigin.

Impresión del funcionamiento del banco de pruebas:

2022.12.28 17:13:46.384    Test_AO_BA (EURUSD,M1)    C_AO_BA:50;0.0;1.0;0.0;1.5;0.0;1.0;0.3;0.3
2022.12.28 17:13:46.384    Test_AO_BA (EURUSD,M1)    =============================
2022.12.28 17:13:48.451    Test_AO_BA (EURUSD,M1)    5 Rastrigin's; Func runs 10000 result: 66.63334336098077
2022.12.28 17:13:48.451    Test_AO_BA (EURUSD,M1)    Score: 0.82562
2022.12.28 17:13:52.630    Test_AO_BA (EURUSD,M1)    25 Rastrigin's; Func runs 10000 result: 65.51391114042588
2022.12.28 17:13:52.630    Test_AO_BA (EURUSD,M1)    Score: 0.81175
2022.12.28 17:14:27.234    Test_AO_BA (EURUSD,M1)    500 Rastrigin's; Func runs 10000 result: 59.84512760590815
2022.12.28 17:14:27.234    Test_AO_BA (EURUSD,M1)    Score: 0.74151
2022.12.28 17:14:27.234    Test_AO_BA (EURUSD,M1)    =============================
2022.12.28 17:14:32.280    Test_AO_BA (EURUSD,M1)    5 Forest's; Func runs 10000 result: 0.5861602092218606
2022.12.28 17:14:32.280    Test_AO_BA (EURUSD,M1)    Score: 0.33156
2022.12.28 17:14:39.204    Test_AO_BA (EURUSD,M1)    25 Forest's; Func runs 10000 result: 0.2895682720055589
2022.12.28 17:14:39.204    Test_AO_BA (EURUSD,M1)    Score: 0.16379
2022.12.28 17:15:14.716    Test_AO_BA (EURUSD,M1)    500 Forest's; Func runs 10000 result: 0.09867854051596259
2022.12.28 17:15:14.716    Test_AO_BA (EURUSD,M1)    Score: 0.05582
2022.12.28 17:15:14.716    Test_AO_BA (EURUSD,M1)    =============================
2022.12.28 17:15:20.843    Test_AO_BA (EURUSD,M1)    5 Megacity's; Func runs 10000 result: 3.3199999999999994
2022.12.28 17:15:20.843    Test_AO_BA (EURUSD,M1)    Score: 0.27667
2022.12.28 17:15:26.624    Test_AO_BA (EURUSD,M1)    25 Megacity's; Func runs 10000 result: 1.2079999999999997
2022.12.28 17:15:26.624    Test_AO_BA (EURUSD,M1)    Score: 0.10067
2022.12.28 17:16:05.013    Test_AO_BA (EURUSD,M1)    500 Megacity's; Func runs 10000 result: 0.40759999999999996
2022.12.28 17:16:05.013    Test_AO_BA (EURUSD,M1)    Score: 0.03397

El algoritmo de murciélago ha mostrado resultados impresionantes en la función de Rastrigin suave y, curiosamente, al aumentar el número de variables en la función, aumenta la estabilidad (repetibilidad) de los resultados, lo cual indica una excelente escalabilidad de BA en funciones suaves. Así, BA ha resultado ser el mejor en la función Rastrigin con 50 y 1000 variables entre todos los participantes de la prueba, lo cual nos permite recomendar el algoritmo de murciélago para trabajar con funciones suaves complejas, y para operar con redes neuronales. En las funciones Forest y Megacity, el algoritmo de murciélago ha obtenido resultados promedio, mostrando cierta tendencia a atascarse en los extremos locales; las coordenadas se localizan en grupos y no muestran la dinámica de cambio y desplazamiento hacia el óptimo global. Es de suponer que este comportamiento del algoritmo se debe a que resulta sensible a la presencia de un gradiente en la superficie de la función analizada; en ausencia de un gradiente, el algoritmo se detiene rápidamente en las proximidades de las áreas locales, que no muestran un incremento significativo en los valores de la función de aptitud, además, el algoritmo BA carece de mecanismos que permitan "saltar" a nuevas áreas desconocidas, similar al mecanismo implementado en COA, con la ayuda de vuelos de Levy.

Debemos detenernos en un aspecto tan importante como es la presencia de un gran número de escenarios para BA. No solo hay muchos parámetros (grados de libertad) en sí mismos, sino que cada uno de los parámetros afecta en gran medida tanto a la naturaleza de las propiedades de búsqueda como a los coeficientes de convergencia generales. Algunos parámetros pueden ofrecer excelentes resultados en funciones suaves y otros en funciones discretas y de torsión; además, encontrar algunos parámetros universales que permitan hacer frente igualmente bien a diferentes tipos de funciones de prueba no es una tarea trivial. Adjuntamos al artículo el código fuente del algoritmo de murciélago con los parámetros que nos parecen óptimos. En general, no recomendamos utilizar BA a usuarios con poca experiencia en el trabajo con algoritmos de optimización, ya que los resultados de la optimización pueden variar mucho.  

rastrigin

  BA en la función de prueba Rastrigin.

forest

BA en la función de prueba Forest.

megacity

BA en la función de prueba Megacity.

Prestando atención a la visualización de las funciones de prueba, uno puede hacerse una idea de los rasgos característicos del algoritmo de murciélago. En concreto, al trabajar en todas las funciones de prueba, el algoritmo se caracteriza por agrupar las coordenadas en áreas locales muy pequeñas, pero si bien para una función suave esta característica permite moverse incluso donde el gradiente de la función de aptitud cambia ligeramente, en un función discreta, en cambio, esta característica manifestará una cierta desventaja, pues el algoritmo se atasca en mesetas planas.

Impresión de los resultados por parte del script para calcular la puntuación de los algoritmos de optimización:

2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_RND=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.18210 | 0.15281 | 0.07011 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.08623 | 0.04810 | 0.06094 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.00000 | 0.00000 | 0.08904 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.6893397068905002
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_PSO=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.22131 | 0.12861 | 0.05966 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.15345 | 0.10486 | 0.28099 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.08028 | 0.02385 | 0.00000 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    1.053004072893302
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_ACOm=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.37458 | 0.28208 | 0.17991 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    1.00000 | 1.00000 | 1.00000 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    1.00000 | 1.00000 | 0.10959 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    5.946151922377553
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_ABC=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.84599 | 0.51308 | 0.22588 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.58850 | 0.21455 | 0.17249 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.47444 | 0.26681 | 0.35941 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    3.661160435265267
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_GWO=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.00000 | 0.00000 | 0.00000 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.00000 | 0.00000 | 0.00000 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.18977 | 0.04119 | 0.01802 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.24898721240154956
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_COAm=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    1.00000 | 0.73390 | 0.28892 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.64504 | 0.34034 | 0.21362 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.67153 | 0.34273 | 0.45422 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    4.690306586791184
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_FSS=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.50663 | 0.39737 | 0.11006 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.07806 | 0.05013 | 0.08423 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.00000 | 0.01084 | 0.18998 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    1.4272897567648186
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_FAm=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.64746 | 0.53292 | 0.18102 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.55408 | 0.42299 | 0.64360 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.21167 | 0.28416 | 1.00000 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    4.477897116029613
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    =======C_AO_BA=======
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.43859 | 1.00000 | 1.00000 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.17768 | 0.17477 | 0.33595 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.15329 | 0.07158 | 0.46287 |
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    3.8147314003892507
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    ================
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    ================
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    ================
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    0.24898721240154956 | 5.946151922377553
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_RND: 8.652
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_PSO: 14.971
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_ACOm: 100.000
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_ABC: 60.294
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_GWO: 1.000
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_COAm: 78.177
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_FSS: 21.475
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_FAm: 74.486
2023.01.03 17:55:57.386    CalculationTestResults (EURUSD,M1)    C_AO_BA: 62.962

Entonces, vamos a pasar a la consideración de la tabla de calificación final. Como hemos mencionado antes, la metodología para calcular las características estimadas de los algoritmos ha cambiado, por lo que los algoritmos ocupan ahora una nueva posición. Hemos eliminado de la tabla algunos algoritmos clásicos, y ahora solo quedan sus versiones modificadas, que muestran un mayor rendimiento en las pruebas. Ahora los resultados de la prueba no son absolutos como lo eran antes (resultados absolutos normalizados de los valores de la función de prueba), sino relativos, basados en los resultados de la comparación de los algoritmos entre sí.

La tabla muestra que el líder absoluto al momento de este artículo es ACOm (optimización de colonias de hormigas), el algoritmo ha mostrado los mejores resultados en cinco de nueve pruebas, por lo que el resultado final será de 100 puntos. En la segunda línea de la clasificación se encuentra COAm, una versión modificada del algoritmo de optimización de cuco. Este algoritmo ha resultado mejor con la función suave de Rastrigin y también ha mostrado buenos resultados en otras pruebas en comparación con otros participantes de la misma. El algoritmo de luciérnaga modificado FAm ha ocupado el tercer puesto, mostrando los mejores resultados con la función discreta Megacity: solo FSS ha mostrado el mismo resultado en esta prueba.

AO

Description

Rastrigin

Rastrigin final

Forest

Forest final

Megacity (discrete)

Megacity final

Final result

10 params (5 F)

50 params (25 F)

1000 params (500 F)

10 params (5 F)

50 params (25 F)

1000 params (500 F)

10 params (5 F)

50 params (25 F)

1000 params (500 F)

ACOm

ant colony optimization M

0,37458

0,28208

0,17991

0,83657

1,00000

1,00000

1,00000

3,00000

1,00000

1,00000

0,10959

2,10959

100,000

COAm

cuckoo optimization algorithm M

1,00000

0,73390

0,28892

2,02282

0,64504

0,34034

0,21362

1,19900

0,67153

0,34273

0,45422

1,46848

78,177

FAm

firefly algorithm M

0,64746

0,53292

0,18102

1,36140

0,55408

0,42299

0,64360

1,62067

0,21167

0,28416

1,00000

1,49583

74,486

BA

bat algorithm

0,43859

1,00000

1,00000

2,43859

0,17768

0,17477

0,33595

0,68840

0,15329

0,07158

0,46287

0,68774

62,962

ABC

artificial bee colony

0,84599

0,51308

0,22588

1,58495

0,58850

0,21455

0,17249

0,97554

0,47444

0,26681

0,35941

1,10066

60,294

FSS

búsqueda de bancos de peces

0,64746

0,53292

0,18102

1,36140

0,55408

0,42299

0,64360

1,62067

0,21167

0,28416

1,00000

1,49583

21,475

PSO

particle swarm optimisation

0,22131

0,12861

0,05966

0,40958

0,15345

0,10486

0,28099

0,53930

0,08028

0,02385

0,00000

0,10413

14,971

RND

random

0,18210

0,15281

0,07011

0,40502

0,08623

0,04810

0,06094

0,19527

0,00000

0,00000

0,08904

0,08904

8,652

GWO

grey wolf optimizer

0,00000

0,00000

0,00000

0,00000

0,00000

0,00000

0,00000

0,00000

0,18977

0,04119

0,01802

0,24898

1,000


Histograma con los resultados de las pruebas de los algoritmos en la Figura 4.

rating

Figura 4. Histograma con los resultados finales de los algoritmos de prueba.

Conclusiones sobre las propiedades del algoritmo de murciélago (BA):

Ventajas:
1. Es rápido.
2. Funciona bien con funciones suaves.
3. Escalabilidad.

Desventajas:
1. Demasiados ajustes.
2. Muestra resultados mediocres en funciones discretas.


Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/11915

Archivos adjuntos |
Cómo construir un EA que opere automáticamente (Parte 10): Automatización (II) Cómo construir un EA que opere automáticamente (Parte 10): Automatización (II)
La automatización no significa nada si no se puede controlar el horario. Ningún trabajador puede ser eficiente trabajando 24 horas al día. Sin embargo, muchos creen que un sistema automatizado debe trabajar 24 horas al día. Siempre es bueno tener formas de configurar una franja horaria para el Expert Advisor. En este artículo, vamos a discutir cómo agregar correctamente tal franja horaria.
Cómo construir un EA que opere automáticamente (Parte 09): Automatización (I) Cómo construir un EA que opere automáticamente (Parte 09): Automatización (I)
Aunque la creación de un Expert Advisor automático no es una tarea muy complicada, sin los conocimientos adecuados, se puede acabar cometiendo muchos errores. En este artículo, vamos a ver cómo construir el primer nivel de automatización, que es crear el disparador para activar breakeven y trailing stop.
Cómo construir un EA que opere automáticamente (Parte 11): Automatización (III) Cómo construir un EA que opere automáticamente (Parte 11): Automatización (III)
Un sistema automatizado sin seguridad no tendrá éxito. Sin embargo, la seguridad no se consigue sin entender bien algunas cosas. En este artículo, comprenderemos por qué es tan difícil lograr la máxima seguridad en los sistemas automatizados.
Aprendiendo a diseñar un sistema comercial con Gator Oscillator Aprendiendo a diseñar un sistema comercial con Gator Oscillator
Bienvenidos a un nuevo artículo de la serie dedicada a la creación de sistemas comerciales basados en indicadores técnicos populares. En esta ocasión, hablaremos sobre el indicador Gator Oscillator y crearemos un sistema comercial utilizando estrategias simples.