Русский 中文 Español Deutsch 日本語
preview
Artificial Electric Field Algorithm (AEFA)

Artificial Electric Field Algorithm (AEFA)

MetaTrader 5Examples | 10 January 2025, 16:50
2 388 0
Andrey Dik
Andrey Dik
Contents
  1. Introduction
  2. Implementation of the algorithm
  3. Test results


Introduction

The artificial electric field algorithm is an amazing creation that embodies the harmony of technology and nature. Inspired by Coulomb's law of electrostatic force, this algorithm attracts attention for its unique ability to model electrical phenomena to solve complex optimization problems. In the context of algorithms already known and described in earlier articles related to the laws of nature, such as Charged System Search (CSS), ElectroMagnetism-like algorithm (ЕМ), Gravitational Search Algorithm (GSA) and others, the artificial electric field is an exciting innovation that will not leave any researcher indifferent.

The artificial electric field algorithm is inspired by Coulomb's law, which states that the electrostatic (attraction or repulsion) force between two charged particles is directly proportional to the product of their charges and inversely proportional to the square of the distance between them. In the proposed algorithm, agents are considered as charged particles, and their strength is measured by their charges. All these particles can attract or repel each other by electrostatic force, and because of this force, objects move in the search space. Therefore, charges are used as a direct form of communication through electrostatic force, and the position of the charge corresponds to the solution of the problem. The charges are defined as a function of the candidate solution fitness and the fitness of the population. In the proposed algorithm, we consider only the attraction of the electrostatic force such that the charged particle with the highest charge (the "best" individual) attracts all other particles with a lower charge and moves slowly in the search space.

Thus, the AEFA can be considered as an isolated system of charges that adhere to Coulomb's first law of electrostatics of electrostatic force and the law of motion (like-charged particles repel each other, and opposite-charged particles attract each other) and Coulomb's second law of electrostatics (the attractive force between oppositely charged particles or the repulsive force between like-charged particles is directly proportional to the product of their charges and inversely proportional to the square of the distance between the centers of charges), as well as the law of motion (the current velocity of any charge is equal to the sum of the fractions of its previous velocity and the changes in velocity). The change in velocity or acceleration of any charge is equal to the force acting on the system divided by the mass of the particle.

AEFA (Artificial Electric Field Algorithm) was developed by:

1. Anita - Department of Sciences and Humanities, Uttarakhand National Institute of Technology, Srinagar, India.
2. Anupam Yadav - Department of Mathematics, Dr. B.R. Ambedkar National Institute of Technology Jalandhar, India.

AEFA was proposed in 2019 and published in the "Swarm and Evolutionary Computation" magazine. The authors of the article note that the concept of an electric field and charged particles gives us a strong theory for how the attractive or repulsive force between two charged particles works. Thus, AEFA uses the principles of electrostatic force to develop a population optimization algorithm.


Implementation of the algorithm

AEFA is rich in various equations and before we move on to them, let us note its key points:

  • The agents of the algorithm (decision) are represented as charged particles moving under the action of electrostatic force.
  • The charge of a particle depends on its personal best result and the current best and worst results in the population (not the best results achieved during optimization, but the current ones in the population).
  • The force acting on a particle depends on the charges of the particles and the distance between them.
  • The Coulomb constant K(t) decreases with increasing iterations, controlling the balance between global search and local optimization.

Let's move on to the formalization of the algorithm and consider in more detail the equations used in it.

Let the position of the i th particle in the d-dimensional search space is denoted as X_i = (x_1, x_2, ..., x_d), where i = 1, 2, ..., N, while N is a pipulation size.
The best position found in the i th particle is denoted as P_i, while the globally best position is denoted as P_best.

1. Coulomb's equation for electrostatic force: F_ij = K * Q_i * Q_j / R^2, where:

  • F_ij - magnitude of the electrostatic force between two charged objects i th and j th
  • K - Coulomb constant
  • Q_i and Q_j - charges of the i th and j th objects respectively
  • R - distance between two charges Q_i and Q_j

2. Equation for the electric field around the Q_i charge: E_i = F_ij / Q_i, where:

  • E_i - electric field around the Q_i charge
  • F_ij - force acting on the Q_i charge

3. Equation for particle acceleration according to Newton's second law: a_i = F_ij / M, where:

  • a_i - acceleration of the i th particle
  • F_ij - force acting on a particle
  • M - particle mass

4. Equation for particle acceleration via the electric field: a_i = E_i * Q_i / M, where:

  • a_i - acceleration of the i th particle
  • E_i - electric field around the particle
  • Q_i - particle charge
  • M - particle mass

5. The equation for updating the best particle position: p_di (t+1) = {p_di (t) and X_i (t+1) = X_i (t)}, if f (X_i (t+1)) > f (X_i (t)), where:

  • p_di (t) - fitness of the i th particle at a given moment t
  • p_di (t+1) - fitness of the i th particle at a given moment (t+1)
  • X_i (t) - position of the i th particle at a given moment t
  • X_i (t+1) - new position of the i th particle at a given moment (t+1)
  • f(X_i (t)) - target function on the previous position of the i th particle at a given moment t
  • f(X_i (t+1)) - target function on the new position of the i th particle at a given moment (t+1)

6. Equation for the force acting on the i th particle from the j th particle: F_dij (t) = K (t) * (Q_i (t) * Q_j (t) * (p_dj (t) - X_di (t))) / (R_ij (t)^2 + ε), where:

  • F_dij (t) - force acting on the i th particle from the j th particle at a given moment t
  • K (t) - Coulomb constant at the moment of t
  • Q_i (t) and Q_j (t) - charges of the i th and j th particles at a given moment t
  • p_dj (t) - best position of the j th particle at the moment of t
  • X_di (t) - position of the i th particle at a given moment in t
  • R_ij (t) - Euclidean distance between the i th and j th particles at a given moment of t
  • ε - small positive constant used to prevent division by 0.

7. Equation for the Euclidean distance between the i th and j th particles: R_ij (t) = (X_i (t) - X_j (t))^2

8. Equation for Coulomb's constant: K (t) = K_0 * exp (-α * t / maxiter), where:

  • K_0 - initial value of the Coulomb constant
  • α - external parameter
  • t - current moment in time (epoch)
  • maxiter - maximum number of iterations

9. Equation for the total force acting on the i th particle: F_di (t) = Σ (rand () * F_dij (t)), j=(from 1 to N), j≠i, where:

  • F_di (t) - total force acting on the i th particle at the moment of t
  • rand () - random number in the interval [0, 1]
  • N - number of particles in the search space

10. Equation for the electric field acting on the i th particle: E_di (t) = F_di (t) / Q_i (t), where:

  • E_di (t) - electric field acting on the i th particle at the moment t
  • F_di (t) - total force acting on the i th particle
  • Q_i (t) - charge of the i th particle at the moment of t

11. The equation updates the particle speed i at the moment of t+1: V_i (t+1) = rand () * V_i (t) + a_i (t), where:

  • V_i(t) - previous speed
  • a_i(t) - acceleration influencing a particle
  • rand () - random number in the interval [0, 1]

12. The equation updates the position of particle i at the time of t+1: X_i (t+1) = X_i (t) + V_i (t+1), where:

  • V_i (t+1) - new speed

13. The equation specifies that the charge of all particles in the population is the same and equal to Q_i (t) = Q_j (t) for all i, j = 1, 2,..., N

14. The equation calculates the relative charge q_i (t) of each particle i at the moment of tq_i (t) = exp ((fit_p_i (t) - worst (t)) / (best (t) - worst (t))), where:

  • fit_p_i (t) - fitness value of the particle personal best position
  • fit_best (t) - fitness value of the global best position
  • fit_worst(t) - fitness value of the worst particle in the population

15. Equation: Q_i (t) = q_i (t) / Σ_j=1...N q_j (t).
The equation normalizes relative charges q_i (t) of all particles so that their sum is equal to 1. In this way, the normalized charges Q_i (t) are obtained for each particle.

16. Equation: best (t) = max (fit_j (t)) for j = 1, 2,..., N
This equation calculates the current best fitness value — the best (t) value in the population as of the moment of t as the maximum of the fitness values of all particles.

17. Equation: worst (t) = min (fit_j (t)) for j = 1, 2,..., N
The equation calculates the current worst fitness value worst (t) in the population as of the moment of t as the minimum of the fitness values of all particles.

Now that we know the equations for the laws of particle motion in the algorithm, we can create a pseudocode that will help us write the AEFA algorithm code in MQL5 in the future.


AEFA pseudocode:

Step 1: Initialization

- Randomly initialize particle positions.
- Calculate the values of the objective function for each particle.
- Set the current iteration t = 0.

Step 2: Update particle positions until the stop condition is met:  

1. Calculate K(t) Coulomb's constant according to the equation (8)
2. Calculate the best fit_best (t) and worst fit_worst(t) values of the target function at the current iteration.
3. For each particle i = 1, 2, ..., N:
   a. Calculate the Q_i (t) particle charge according to the equation (14)
   b. Calculate the force acting on particle i from the particle j according to the equation (6)
   c. Calculate the total force acting on the particle i using the equation (9)
   d. Calculate the acceleration of the particle i using the equation (4)
   e. Update speed using the equation (11) and i particle position using the equation (12)
4. Increase iteration counter t = t + 1

Step 3: Stop condition. Check the stop condition (e.g. reaching the maximum number of iterations). If the condition is not met, move on to Step 2.

K0

Figure 1. Dependence of electrostatic force according to Coulomb's formula on the α ratio (external parameter).

Well, finally we figured out the description, equations and pseudocode of the algorithm. Now we need to move on to generating the code.

Let's implement the S_AEFA_Agent structure, which serves to describe agents in the algorithm. The structure contains the following fields:

  • best_fitness - the variable represents the best fitness of the agent.
  • best_position[] - array of coordinates of the agent's best position in the search space.
  • velocity[] - array representing the particle's velocity vector.
  • charge - agent charge.
  • relative_charge - relative charge of the particle.

The structure also defines the Init function, which initializes the particle (agent). It takes the coords parameter, which denotes the number of agent coordinates and changes the sizes of the best_position and velocity arrays respectively. After that, set best_fitness to the minimum possible double value of -DBL_MAX, while charge and relative_charge are set to 0.

The code provides a basis for describing agents in the artificial electric field algorithm and prepares them for further work in this context.

//——————————————————————————————————————————————————————————————————————————————
struct S_AEFA_Agent
{
    double best_fitness;
    double best_position [];
    double velocity      [];
    double charge;
    double relative_charge;

    void Init (int coords)
    {
      ArrayResize (best_position, coords);
      ArrayResize (velocity,      coords);

      best_fitness    = -DBL_MAX;
      charge          = 0;
      relative_charge = 0;
    }
};
//——————————————————————————————————————————————————————————————————————————————

Let's describe the C_AO_AEFA class inherited from the C_AO class. The following methods and variables are defined inside the class:

  • C_AO_AEFA - constructor, in which the values of variables and parameters are set.
  • SetParams -  method sets the parameters based on the values stored in the params array.
  • Init - method takes a set of values and performs initialization.
  • Moving and Revision - the methods perform the main logic of the algorithm.
  • Several variables of double type, such as K0, alpha, particleMass, epsilon, as well as the agent array and other private variables.
  • The CalculateK, UpdateCharges, CalculateForces, CalculateDistance and UpdateVelocityAndPosition private methods perform operations to move particles in the search space.
//——————————————————————————————————————————————————————————————————————————————
class C_AO_AEFA : public C_AO
{
  public: //--------------------------------------------------------------------
  ~C_AO_AEFA () { }
  C_AO_AEFA ()
  {
    ao_name = "AEFA";
    ao_desc = "Artificial Electric Field Algorithm";
    ao_link = ""; //"https://www.mql5.com/en/articles/15162";

    popSize      = 50;
    K0           = 500.0;
    alpha        = 20.0;
    particleMass = 1.0;

    ArrayResize (params, 4);

    params [0].name = "popSize";       params [0].val = popSize;
    params [1].name = "K0";            params [1].val = K0;
    params [2].name = "alpha";         params [2].val = alpha;
    params [3].name = "particleMass";  params [3].val = particleMass;
  }

  void SetParams ()
  {
    popSize      = (int)params [0].val;
    K0           = params      [1].val;
    alpha        = params      [2].val;
    particleMass = params      [3].val;
  }

  bool Init (const double &rangeMinP  [],
             const double &rangeMaxP  [],
             const double &rangeStepP [],
             const int     epochsP = 0);

  void Moving ();
  void Revision ();

  //----------------------------------------------------------------------------
  double K0;
  double alpha;
  double particleMass;
  double epsilon;

  S_AEFA_Agent agent [];

  private: //-------------------------------------------------------------------
  int    epochs;
  int    epochNow;
  double K;
  double CalculateK                (int t);
  void   UpdateCharges             (double best, double worst);
  void   CalculateForces           ();
  double CalculateDistance         (const double &x1 [], const double &x2 []);
  void   UpdateVelocityAndPosition (int i);
};
//——————————————————————————————————————————————————————————————————————————————

Next, move on to implementing the Init method of the C_AO_AEFA class. The method initializes the AEFA algorithm with the given parameters.

The inputs of the Init method:

  • rangeMinP - array of values of the minimum range boundaries.
  • rangeMaxP - array of values of the maximum range limits.
  • rangeStepP - array of range step values.
  • epochsP - number of epochs (default is 0).

Actions performed in the Init method:

1. The StandardInit method is called. It receives the rangeMinP, rangeMaxP and rangeStepP arrays. If the StandardInit method returns false, the Init returns false.
2. epochs and epochNow variables are set equal to epochsP and 0 respectively.
3. The agent array is resized to popSize.
4. In the loop, each element of the agent array is initialized by calling the Init method by passing the coords array to it.
5. The epsilon variable is set equal to 1e-10.
6. The method returns true.

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

  //----------------------------------------------------------------------------
  epochs   = epochsP;
  epochNow = 0;

  ArrayResize (agent, popSize);
  for (int i = 0; i < popSize; i++) agent [i].Init (coords);

  epsilon = 1e-10;

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

Let's move on to the Moving() method of the C_AO_AEFA class. In this method, the particle positions are updated in the optimization algorithm. Here is a quick rundown of what is going on:

1. The value of the epochNow variable is increased.
2. If the revision variable is equal to false, the initial positions of the particles are initialized. Each particle coordinate is set to a random value in a given range, then this value is transformed according to a given step.
3. If revision is equal to true, the K value is calculated together with the best and worst function estimates for each particle. Forces are calculated, and speed and position of each particle are updated together with the charges.

The general idea of this method is to update the positions of particles in the optimization algorithm using special methods for calculating the equations of the particle motion laws.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_AEFA::Moving ()
{
  epochNow++;

  //----------------------------------------------------------------------------
  if (!revision)
  {
    for (int i = 0; i < popSize; i++)
    {
      for (int c = 0; c < coords; c++)
      {
        a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
        a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }

    revision = true;
    return;
  }

  //----------------------------------------------------------------------------
  K            = CalculateK (epochNow);
  double best  = -DBL_MAX;
  double worst =  DBL_MAX;

  for (int i = 0; i < popSize; i++)
  {
    if (a [i].f > best)  best  = a [i].f;
    if (a [i].f < worst) worst = a [i].f;
  }

  UpdateCharges   (best, worst);
  CalculateForces ();

  for (int i = 0; i < popSize; i++)
  {
    UpdateVelocityAndPosition (i);
  }
}
//——————————————————————————————————————————————————————————————————————————————

In the CalculateK() method of the C_AO_AEFA class, calculate the K parameter based on t (current epoch index) and other parameters K0, alpha and epochs. Here is what happens in this method:

1. The method takes the parameter t as input, which represents the index of the current epoch in the algorithm.
2. Then the K value is calculated.
3. The result of the calculation based on the equation is returned as the method value.

//——————————————————————————————————————————————————————————————————————————————
double C_AO_AEFA::CalculateK (int t)
{
  return K0 * MathExp (-alpha * t / epochs);
}
//——————————————————————————————————————————————————————————————————————————————

In the UpdateCharges() method of the C_AO_AEFA class, update the particle chanrges based on the best and worst fitness values. Brief description of the actions in the method:

1. The sum_q variable is created and set to 0.
2. Then a cycle occurs through all particles within the range from 0 to popSize.
3. Inside the loop, the relative charge for each particle is calculated using the equation.
4. The relative charge value is added to the sum_q variable.
5. Then a second loop occurs over all particles, in which each particle is assigned a charge value equal to the relative charge divided by sum_q.

This method thus updates the particle charges based on their fitness so that they reflect their relative quality compared to the best and worst fitness values.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_AEFA::UpdateCharges (double best, double worst)
{
  double sum_q = 0;

  for (int i = 0; i < popSize; i++)
  {
    agent [i].relative_charge = MathExp ((a [i].f - worst) / (best - worst));
    sum_q += agent [i].relative_charge;
  }
  for (int i = 0; i < popSize; i++)
  {
    agent [i].charge = agent [i].relative_charge / sum_q;
  }
}
//——————————————————————————————————————————————————————————————————————————————

Let's provide the CalculateForces() and CalculateDistance() methods of the C_AO_AEFA class.

The CalculateDistance() method accepts two arrays x1[] and x2[], representing the coordinates of two particles, and calculates the spatial distance between them. To do this, it iterates over all the coordinates of the arrays, and for each coordinate the square of the difference of the arrays' corresponding elements is calculated, after which these squares are summed up. The square root of the resulting sum is then extracted and this value is returned as the distance between two points in space (Euclidean distance).

The CalculateForces() method calculates the forces acting on each particle. For each particle, the force vector is calculated in relation to all other particles. For each pair of particles, except for identical ones (i != j), the distance between them is calculated using the CalculateDistance() method. Then, for each coordinate in space, the force acting on the particle is calculated using an equation that includes the charges of the particles, their positions, and the distance between them. The results are summed for each coordinate, and the resulting forces are then divided by the particle charge to account for their effect on the particle speed.

Thus, the methods perform calculations of the forces acting between particles in the algorithm and the distances between them in space, respectively.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_AEFA::CalculateForces ()
{
  double force [];
  ArrayResize (force, coords);

  for (int i = 0; i < popSize; i++)
  {
    ArrayInitialize (force, 0);

    for (int j = 0; j < popSize; j++)
    {
      if (i != j)
      {
        double R = CalculateDistance (a [i].c, a [j].c);

        for (int d = 0; d < coords; d++)
        {
          force [d] += u.RNDprobab () * K *
                       (agent [i].charge * agent [j].charge * (agent [j].best_position [d] - a [i].c [d])) /
                       (R * R + epsilon);
        }
      }
    }

    for (int d = 0; d < coords; d++)
    {
      agent [i].velocity [d] = force [d] / agent [i].charge;
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

//——————————————————————————————————————————————————————————————————————————————
double C_AO_AEFA::CalculateDistance (const double &x1 [], const double &x2 [])
{
  double sum = 0;
  for (int d = 0; d < coords; d++)
  {
    sum += (x1 [d] - x2 [d]) * (x1 [d] - x2 [d]);
  }
  return MathSqrt (sum);
}
//——————————————————————————————————————————————————————————————————————————————

Next comes the UpdateVelocityAndPosition() method of the C_AO_AEFA class. This method updates the velocity and position of the particle with index i. The following happens for each coordinate of a particle in space:

1. The acceleration is calculated, which depends on the charge of the particle, its current speed and the particle mass.
2. The particle speed is updated by adding a random component multiplied by the current speed and acceleration.
3. The particle position is updated by adding the new velocity to the current position. The new position is then constrained within the specified minimum and maximum values for each coordinate using u.SeInDiSp().

Thus, the UpdateVelocityAndPosition() method updates the particle velocity and position in the optimization algorithm, taking into account acceleration, random factors, and constraints on the particle position in space.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_AEFA::UpdateVelocityAndPosition (int i)
{
  for (int d = 0; d < coords; d++)
  {
    double acceleration = (agent [i].charge * agent [i].velocity [d]) / particleMass;

    agent [i].velocity [d] = (u.RNDfromCI (0, 1)) * agent [i].velocity [d] + acceleration;

    a [i].c [d] += agent [i].velocity [d];
    a [i].c [d] = u.SeInDiSp (a [i].c [d], rangeMin [d], rangeMax [d], rangeStep [d]);
  }
}
//——————————————————————————————————————————————————————————————————————————————

Finally, we have the Revision() method of the C_AO_AEFA class. In this method, information about the best positions of particles and their best fitness values, as well as the fB best global solution, is updated. The method does the following:

1. The ind variable is created as a flag and an index of the position in the best solution array and is set to -1.
2. Then a cycle occurs through all particles within the range from 0 to popSize.
3. Inside the loop, it is checked whether the value of the particle fitness function exceeds the fB value. If yes, fB is updated and the ind variable is set to i.
4. It is then checked whether the fitness of the particle is greater than the best fitness of that particle over all epochs (stored in agent[i].best_fitness). If yes, the best score and position are updated.
5. Finally, if ind is not equal to -1, the cB position is updated by copying the position of the particle with the ind index.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_AEFA::Revision ()
{
  int ind = -1;

  for (int i = 0; i < popSize; i++)
  {
    if (a [i].f > fB)
    {
      fB = a [i].f;
      ind = i;
    }

    if (a [i].f > agent [i].best_fitness)
    {
      agent [i].best_fitness = a [i].f;
      ArrayCopy (agent [i].best_position, a [i].c, 0, 0, WHOLE_ARRAY);
    }
  }

  if (ind != -1) ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY);
}
//——————————————————————————————————————————————————————————————————————————————


3. Test results

AEFA test stand results:

AEFA|Artificial Electric Field Algorithm|20.0|1000.0|10.0|100.0|
=============================
5 Hilly's; Func runs: 10000; result: 0.8769988087850553
25 Hilly's; Func runs: 10000; result: 0.617530930198765
500 Hilly's; Func runs: 10000; result: 0.2523539056281608
=============================
5 Forest's; Func runs: 10000; result: 0.927287032866128
25 Forest's; Func runs: 10000; result: 0.7269761843712702
500 Forest's; Func runs: 10000; result: 0.18063577020760296
=============================
5 Megacity's; Func runs: 10000; result: 0.6661538461538462
25 Megacity's; Func runs: 10000; result: 0.11630769230769236
500 Megacity's; Func runs: 10000; result: 0.0950769230769239
=============================
All score: 4.45932 (49.55%)

We can see a significant spread of results from test to test. In addition, the algorithm demonstrates very weak search capabilities when working with high-dimensional functions, which is also confirmed by its results. Special problems have been identified when working with discrete functions.

Hilly

  AEFA on the Hilly test function

Forest

  AEFA on the Forest test function

  AEFA on the Megacity test function

I would like to highlight one important aspect of the AEFA algorithm. After conducting standard tests with 10 000 launches of the fitness function, I decided to conduct an additional experiment with an increase in the number of launches to 100 000, and the result exceeded my expectations. On many functions with a small number of parameters, the algorithm achieved 100% convergence with an increase in the number of fitness function runs. It is important to note that not all algorithms in the ranking table, even those occupying the top positions, can achieve 100% convergence with an increase in the number of runs, since they get stuck in local extremes. In this case, the algorithm demonstrates resistance to getting stuck. However, the algorithm faces the same difficulties when searching in multidimensional spaces, especially for discrete functions.

AEFA test stand results with 100 000 test functions running:

SDSm|Stochastic Diffusion Search M|100.0|100.0|0.05|
=============================
5 Hilly's; Func runs: 100000; result: 0.9874670077970368
25 Hilly's; Func runs: 100000; result: 0.9355482229513405
500 Hilly's; Func runs: 100000; result: 0.5943074120378588
=============================
5 Forest's; Func runs: 100000; result: 0.994126703499673
25 Forest's; Func runs: 100000; result: 0.9627011069578397
500 Forest's; Func runs: 100000; result: 0.5628894538341265
=============================
5 Megacity's; Func runs: 100000; result: 0.9015384615384615
25 Megacity's; Func runs: 100000; result: 0.7264615384615385
500 Megacity's; Func runs: 100000; result: 0.37464615384615396
=============================
All score: 7.03969 (78.22%)

You can notice this feature of the algorithm convergence in the images below.

MrunsHilly

MrunsForest

MrunsMegacity

Rating table of population optimization algorithms:

# AO Description Hilly Hilly final Forest Forest final Megacity (discrete) Megacity final Final result % of MAX
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 BGA binary genetic algorithm 0.99989 0.99518 0.42835 2.42341 0.96153 0.96181 0.32027 2.24360 0.91385 0.95908 0.24220 2.11512 6.782 75.36
2 ANS across neighbourhood search 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
3 CLA code lock algorithm 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
4 (P+O)ES (P+O) evolution strategies 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 comet tail algorithm 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 SDSm stochastic diffusion search 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
7 ESG evolution of social groups 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
8 SIA simulated isotropic annealing 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
9 ACS artificial cooperative search 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
10 TSEA turtle shell evolution algorithm 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
11 DE differential evolution 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
12 CRO chemical reaction optimization 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
13 BSA bird swarm algorithm 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
14 HS harmony search 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
15 SSG saplings sowing and growing 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
16 (PO)ES (PO) evolution strategies 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
17 BSO brain storm optimization 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
18 WOAm wale optimization algorithm 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
19 AEFA artificial electric field algorithm 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
20 ACOm ant colony optimization 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
21 BFO-GA bacterial foraging optimization - 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
22 MEC mind evolutionary computation 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
23 IWO invasive weed optimization 0.72679 0.52256 0.33123 1.58058 0.70756 0.33955 0.07484 1.12196 0.42333 0.23067 0.04617 0.70017 3.403 37.81
24 Micro-AIS micro artificial immune system 0.79547 0.51922 0.30861 1.62330 0.72956 0.36879 0.09398 1.19233 0.37667 0.15867 0.02802 0.56335 3.379 37.54
25 COAm cuckoo optimization algorithm M 0.75820 0.48652 0.31369 1.55841 0.74054 0.28051 0.05599 1.07704 0.50500 0.17467 0.03380 0.71347 3.349 37.21
26 SDOm spiral dynamics optimization M 0.74601 0.44623 0.29687 1.48912 0.70204 0.34678 0.10944 1.15826 0.42833 0.16767 0.03663 0.63263 3.280 36.44
27 NMm Nelder-Mead method M 0.73807 0.50598 0.31342 1.55747 0.63674 0.28302 0.08221 1.00197 0.44667 0.18667 0.04028 0.67362 3.233 35.92
28 FAm firefly algorithm M 0.58634 0.47228 0.32276 1.38138 0.68467 0.37439 0.10908 1.16814 0.28667 0.16467 0.04722 0.49855 3.048 33.87
29 GSA gravitational search algorithm 0.64757 0.49197 0.30062 1.44016 0.53962 0.36353 0.09945 1.00260 0.32667 0.12200 0.01917 0.46783 2.911 32.34
30 BFO bacterial foraging optimization 0.61171 0.43270 0.31318 1.35759 0.54410 0.21511 0.05676 0.81597 0.42167 0.13800 0.03195 0.59162 2.765 30.72
31 ABC artificial bee colony 0.63377 0.42402 0.30892 1.36671 0.55103 0.21874 0.05623 0.82600 0.34000 0.14200 0.03102 0.51302 2.706 30.06
32 BA bat algorithm 0.59761 0.45911 0.35242 1.40915 0.40321 0.19313 0.07175 0.66810 0.21000 0.10100 0.03517 0.34617 2.423 26.93
33 SA simulated annealing 0.55787 0.42177 0.31549 1.29513 0.34998 0.15259 0.05023 0.55280 0.31167 0.10033 0.02883 0.44083 2.289 25.43
34 IWDm intelligent water drops M 0.54501 0.37897 0.30124 1.22522 0.46104 0.14704 0.04369 0.65177 0.25833 0.09700 0.02308 0.37842 2.255 25.06
35 PSO particle swarm optimisation 0.59726 0.36923 0.29928 1.26577 0.37237 0.16324 0.07010 0.60572 0.25667 0.08000 0.02157 0.35823 2.230 24.77
36 Boids boids algorithm 0.43340 0.30581 0.25425 0.99346 0.35718 0.20160 0.15708 0.71586 0.27846 0.14277 0.09834 0.51957 2.229 24.77
37 MA monkey algorithm 0.59107 0.42681 0.31816 1.33604 0.31138 0.14069 0.06612 0.51819 0.22833 0.08567 0.02790 0.34190 2.196 24.40
38 SFL shuffled frog-leaping 0.53925 0.35816 0.29809 1.19551 0.37141 0.11427 0.04051 0.52618 0.27167 0.08667 0.02402 0.38235 2.104 23.38
39 FSS fish school search 0.55669 0.39992 0.31172 1.26833 0.31009 0.11889 0.04569 0.47467 0.21167 0.07633 0.02488 0.31288 2.056 22.84
40 RND random 0.52033 0.36068 0.30133 1.18234 0.31335 0.11787 0.04354 0.47476 0.25333 0.07933 0.02382 0.35648 2.014 22.37
41 GWO grey wolf optimizer 0.59169 0.36561 0.29595 1.25326 0.24499 0.09047 0.03612 0.37158 0.27667 0.08567 0.02170 0.38403 2.009 22.32
42 CSS charged system search 0.44252 0.35454 0.35201 1.14907 0.24140 0.11345 0.06814 0.42299 0.18333 0.06300 0.02322 0.26955 1.842 20.46
43 EM electroMagnetism-like algorithm 0.46250 0.34594 0.32285 1.13129 0.21245 0.09783 0.10057 0.41085 0.15667 0.06033 0.02712 0.24412 1.786 19.85


Summary

Based on the results of the Artificial Electric Field Algorithm (AEFA) on test functions of different dimensions, the following conclusions can be drawn:

1. AEFA shows satisfactory results on various test functions including Hilly, Forest and Megacity. However, the results on the discrete Megacity function are inferior to other functions.
2. The algorithm demonstrates good performance with a large number of function runs (100 000), which allows improving the convergence accuracy up to 100% on small dimensions.
3. AEFA has an overall score of 4.45932 (49.55%) and is ranked 19 th in the rating table taking place somewhere in the middle.

Although the AEFA algorithm does not show the best results on test functions of different dimensions in our standard tests, it has an additional advantage: with increasing number of fitness function runs, it achieves an impressive overall result of 7.03969 (78.22%), which makes it useful in tasks involving small dimensions, especially those with smooth surfaces.

Tab

Figure 2. Color gradation of algorithms according to relevant tests Results greater than or equal to 0.99 are highlighted in white

chart

Figure 3. The histogram of algorithm test results (on a scale from 0 to 100, the more the better,

where 100 is the maximum possible theoretical result, the archive features a script for calculating the rating table)


AEFA pros and cons:

Advantages:

  1. Excellent convergence on smooth functions of low dimension with a sufficient number of fitness function runs.
  2. Relatively small number of external parameters.

Disadvantages:

  1. Large range of results on the functions used in our standard tests.
  2. Weak results on discrete functions.
  3. Very low scalability.
  4. Complex implementation.

The article is accompanied by an archive with the current versions of the algorithm codes. The author of the article is not responsible for the absolute accuracy in the description of canonical algorithms. Changes have been made to many of them to improve search capabilities. The conclusions and judgments presented in the articles are based on the results of the experiments.

Translated from Russian by MetaQuotes Ltd.
Original article: https://www.mql5.com/ru/articles/15162

Attached files |
AEFA.zip (26.78 KB)
Reimagining Classic Strategies (Part 13): Minimizing The Lag in Moving Average Cross-Overs Reimagining Classic Strategies (Part 13): Minimizing The Lag in Moving Average Cross-Overs
Moving average cross-overs are widely known by traders in our community, and yet the core of the strategy has changed very little since its inception. In this discussion, we will present you with a slight adjustment to the original strategy, that aims to minimize the lag present in the trading strategy. All fans of the original strategy, could consider revising the strategy in accordance with the insights we will discuss today. By using 2 moving averages with the same period, we reduce the lag in the trading strategy considerably, without violating the foundational principles of the strategy.
News Trading Made Easy (Part 6): Performing Trades (III) News Trading Made Easy (Part 6): Performing Trades (III)
In this article news filtration for individual news events based on their IDs will be implemented. In addition, previous SQL queries will be improved to provide additional information or reduce the query's runtime. Furthermore, the code built in the previous articles will be made functional.
Ensemble methods to enhance classification tasks in MQL5 Ensemble methods to enhance classification tasks in MQL5
In this article, we present the implementation of several ensemble classifiers in MQL5 and discuss their efficacy in varying situations.
Developing a multi-currency Expert Advisor (Part 14): Adaptive volume change in risk manager Developing a multi-currency Expert Advisor (Part 14): Adaptive volume change in risk manager
The previously developed risk manager contained only basic functionality. Let's try to consider possible ways of its development, allowing us to improve trading results without interfering with the logic of trading strategies.