Dolphin Echolocation Algorithm (DEA) - MQL5 Articles

Table of Contents
- Introduction
- Algorithm Implementation
- Test Results
Introduction
With each new publication, we move closer to our primary objective: finding an optimal algorithm for addressing the optimization challenges faced by our trading robots. In this article, we will explore another nature-inspired algorithm, specifically one based on the echolocation abilities of certain deep-sea creatures.
Imagine a dolphin hunting in the ocean's pitch-black depths. Visibility is almost zero, yet it accurately locates prey with astonishing precision.
The secret to its success lies in a unique ability: the dolphin emits a series of clicks and, by analyzing the reflected echo, constructs a detailed map of its surroundings. Notably, the frequency of these clicks varies: infrequent clicks are used for general exploration, while rapid clicks are employed when closing in on a target.
This unusual strategy forms the foundation of the Dolphin Echolocation Algorithm (DEA).
In the field of optimization, we often encounter a similar problem: how to find the best solution within a vast space of possibilities without complete information. Much like the dolphin in the ocean, we begin with a broad search, gradually narrowing it down to the most promising areas.
Algorithm Implementation
To better understand the principles of this algorithm, consider the following scenario. You and your friends are searching for gold on a long beach, equipped with metal detectors.
At the start, it's logical to spread out across the entire area, increasing the likelihood of finding something interesting. However, as soon as one of you detects a strong signal, that person informs the others, and gradually, the entire team converges on the promising spots.
By the end of the search, everyone is focused on excavating the area with the strongest signal. This, in essence, is the Dolphin Echolocation Algorithm.
Within the algorithm, the role of dolphins is played by "search agents" — points in the space of possible solutions. Each "dolphin" represents a potential solution to the problem. For instance, if we're looking for the minimum of a simple function like y = x², one dolphin might be at x = -3 (where y = 9), another at x = 1 (where y = 1), and a third might accidentally land at x = 0 (where y = 0) — this third one would become our "champion."
But how do dolphins exchange information? This is where the concept of "effective radius," denoted as "Re," comes into play.
Imagine how far the light from a flashlight spreads. With Re = 1, we have a narrow beam that illuminates only the immediate vicinity.
With Re = 3, the light spreads wider, covering more area. At Re = 5 or more, the search resembles using a spotlight.
In the context of the algorithm, this means that information about a good solution propagates to neighboring areas, with the strength of influence decreasing with distance.
All this information is collected in a "prospectivity map," which the algorithm calls "Accumulated Fitness" (AF). Imagine a city's heat map, where "hot" zones indicate areas of high activity.
In our case, "hot" zones are places where dolphins have found good solutions (prey). The more successful findings in a particular area, the "hotter" it becomes, attracting other dolphins.
However, the algorithm acts more intelligently than simply congregating in one spot. It uses a parameter called "Predetermined Probability" (PP), which balances exploration of new areas with exploitation of already-found promising locations.
1, the algorithm actively experiments. 5, it relies more on proven approaches.
As PP approaches 1, it uses only the most efficient methods.
Let's consider a concrete example of the algorithm's operation. Suppose we are searching for the highest point in a hilly terrain.
At the beginning of the search, our dolphins are randomly scattered across the entire area — some in valleys, some on slopes, and some fortunate enough to be on a hilltop. After evaluating the height of each position, the algorithm determines that the dolphin on the hilltop found the best spot.
" This forces other dolphins to explore nearby areas instead of clustering at a single point. This approach helps avoid premature convergence and find other potentially good solutions.
As the algorithm progresses, the situation changes. At the 50th iteration, we observe that dolphins begin to cluster in hilly areas, but still maintain some diversity.
By the 100th iteration, most of them concentrate in the highest points of the terrain, and eventually, all dolphins focus around the global maximum. The algorithm's effectiveness depends on proper parameter tuning.
Choosing an effective radius Re is critical for balancing local and global search. With Re = 1, we get a very precise but narrowly focused search — like looking for a needle in a haystack with a magnifying glass.
Increasing Re to 3-4 provides a balanced approach, similar to searching with a flashlight. And when Re exceeds 5, the algorithm works like a spotlight, covering large areas but sacrificing precision.
The Power parameter determines how rapidly the algorithm switches from exploration to exploitation. With Power = 1, this transition is smooth and gradual. A Power value of 2 (recommended) provides a more pronounced transition, while values of 3 and above lead to a sharper switch, which can be useful for certain types of tasks.
The initial probability PP1 sets the initial balance between exploration and exploitation. A low value (0.05) signifies aggressive exploration of the space, a standard value of 0.1 provides a good balance, and a high value (0.5) leads to rapid concentration on discovered solutions.
The main advantage of DEA is its adaptability: the algorithm automatically adjusts the balance between exploring new areas and delving deeper into promising zones. Furthermore, it remains relatively simple, requiring the tuning of only four parameters. The information propagation mechanism through accumulated fitness allows effective use of knowledge about the search space, and the "resetting" of AF for the best positions helps avoid getting stuck in local optima.
Of course, the algorithm also has some limitations. It requires additional memory to store the accumulated fitness of all alternatives, which can be a problem for very large search spaces.
And perhaps another point: the algorithm's efficiency depends on the correct choice of the effective radius Re. A schematic representation of the algorithm's operation is shown below.
<image>Figure 1. DEA Algorithm Operation
The main stages of the DEA algorithm are shown in the figure:
- Initial Exploration — Dolphins (search agents) are randomly placed with an echolocation radius Re.
- Accumulated Fitness (AF) Distribution — Shows how AF accumulates around dolphin positions.
- Convergence Process — Consists of three substages that demonstrate the transition from exploration to exploitation.
The illustration helps us understand how dolphins use echolocation to find an optimum, how information propagates through accumulated fitness, how the "Re" parameter affects the search width, and how "PP" regulates the balance between exploration and exploitation. Key concepts - formulas for PP (predetermined probability) and AF.
Algorithm flowchart - main steps with a loop. Influence of the Re parameter - visualization of narrow, medium, and wide radii of influence.
The color scheme in the figure: blue - ordinary dolphins, red - best solution, blue gradients - accumulated fitness levels, gray - search space.
Now, with a general understanding of the algorithm, we can proceed to write detailed pseudocode.
Input Data:
- Number of dolphins (search agents)
- Size of the effective echolocation radius
- Convergence curve power
- Initial predetermined probability
- Search space boundaries and discretization step for each dimension
Initialization:
Creating the Alternative Space:
- For each dimension of the search space, a set of possible alternatives is formed.
- If a discretization step is specified, alternatives are created with that step from the minimum to the maximum value.
- If no step is specified, 500 uniformly distributed alternatives are generated.
- The effective radius is checked: it must not exceed one-quarter of the total number of alternatives.
Initial Placement of Dolphins:
- All dolphins are randomly placed in the search space.
- For each dolphin, the quality of its position (fitness) is calculated.
- Accumulated fitness for all alternatives is initialized to zero.
Main Optimization Loop:
Repeats for a specified number of iterations:
Phase 1. Calculate Predetermined Probability
The probability of preserving the best position in the current iteration is calculated. At the beginning of the process, this probability equals the initial value, then gradually increases via a power function to one by the end of the optimization.
Phase 2. Calculate Dynamic Adaptation Coefficient
A coefficient is calculated that determines the balance between local and global search. This coefficient is the ratio of the difference between the best and worst solutions to the sum of deviations of all solutions from the best. When the population is diverse, the coefficient is high; when it converges, it is low.
Phase 3. Accumulate Fitness Information
For each dolphin:
- Its fitness is normalized relative to the current population range.
- For each coordinate, the nearest alternative to the dolphin's position is found.
- Quality information is propagated within the echolocation radius from this alternative.
- The strength of influence linearly decreases with distance from the center.
- Reflection at the boundaries of the space is applied to preserve information.
- A small value is added to all accumulated fitness values to avoid zero probabilities.
Phase 4. Reset Information for Best Position
The dolphin with the best solution is found, and the accumulated fitness for the alternatives corresponding to its coordinates is reset to zero. This prevents excessive concentration of the search in one point.
Phase 5. Select New Positions
For each dolphin and each of its coordinates:
- If it's the best dolphin and there's a chance to keep its position, the coordinate remains unchanged.
- Otherwise, if there's accumulated fitness information, a new alternative is chosen proportionally to this information using the roulette wheel method.
- If accumulated information is missing or insufficient:
- with a probability equal to the dynamic coefficient, a local search is performed within the echolocation radius;
- otherwise, a global search is performed by selecting a random alternative.
- Search space boundaries and discretization are applied.
Phase 6. Evaluate New Positions
The solution quality for each dolphin at its new position is calculated.
Phase 7. Update Global Information
Records of the best and worst solutions in the population are updated. If a solution better than the current global optimum is found, it is saved.
Completion:
Upon completion of all iterations, the best found solution and its quality are returned.
Now, let's proceed with the DEA implementation.
We will write the S_Alternative structure. It is designed to store information about a specific alternative in the decision-making process for optimization and contains the value field (a value characterizing this alternative, an effectiveness evaluation, and AF) — the accumulated fitness for this alternative, which is necessary to evaluate the quality of the alternative when used in an iterative process.
1//————————————————————————————————————————————————————————————————————
2struct S_Alternative
3{
4 double value; // alternative value
5 double AF; // accumulated fitness for this alternative
6};
7//————————————————————————————————————————————————————————————————————The S_Coordinate structure is designed to represent a set of alternatives associated with a specific coordinate. The alt field is an array of alternatives, each corresponding to a particular coordinate, and count is a variable indicating the current number of alternatives actually stored in the alt array.
1//————————————————————————————————————————————————————————————————————
2struct S_Coordinate
3{
4 S_Alternative alt []; // array of alternatives for a given coordinate
5 int count; // number of alternatives
6};
7//————————————————————————————————————————————————————————————————————Next, we move to the description of the class that directly implements the optimization algorithm (DEA). The C_AO_DEA class inherits from the base class C_AO. When an object of this class is created, the main algorithm parameters are initialized:
popSize— sets the population size (number of "dolphins" or locations).Re— initial value of the effective search radius.Power— convergence curve power.PP1— initial value of the convergence factor for the first iteration.
Then, the params array, used to store user-defined algorithm parameters, is initialized. The initial values popSize, Re, Power, PP1 are copied into it with corresponding names.
The SetParams method is intended to update the internal algorithm parameters based on the values recorded in the params array. After extracting the popSize, Re, Power, PP1 values, their validation is performed.
Methods:
Initis responsible for initializing the algorithm, accepting minimum, maximum values, and steps for each parameter, as well as the total number of epochs (iterations).Movingmoves the "dolphins" in the search space; this is part of the main optimization loop.Revisionadjusts population positions and parameters after movement.
The following fields are used internally for the algorithm's operation and are not accessible from outside the class.
PP— a floating-point number representing the predetermined probability for the current iteration, used for stochastic decisions.currentEpoch— a variable that tracks the current epoch (iteration) of the algorithm.totalEpochs— a value storing the total planned number of epochs.coeffA— a dynamic coefficient used for selecting positions.coordData— an array of structures, where eachS_Coordinatecontains an array of alternatives and their count for a specific coordinate.
Methods:
CalculatePPcalculates the value of PP (predetermined probability) at the current iteration.CalculateAccumulativeFitnesscalculates the accumulated fitness for each alternative.ResetAFforBestLocationresets the accumulated fitness values for the best locations.SelectNextLocationsselects the next locations for dolphins based on the current state.FindNearestAlternativefinds the nearest alternative based on given coordinates and value.CalculateCoefficientAcalculates the dynamic coefficientcoeffA.
Overall, the C_AO_DEA class is ready for use to find solutions in a multidimensional space. It has public methods for initialization and execution of the main optimization steps, as well as private methods and data that implement the internal logic of the algorithm.
1//————————————————————————————————————————————————————————————————————
2class C_AO_DEA : public C_AO
3{
4 public: //----------------------------------------------------------
5 ~C_AO_DEA { }
6 C_AO_DEA
7 {
8 ao_name = "DEA";
9 ao_desc = "Dolphin Echolocation Algorithm";
10 ao_link = "https://www.mql5.com/en/articles/12204"; // Placeholder for specific link
11
12 popSize = 100; // NL - number of locations (dolphins)
13 Re = 2; // effective search radius
14 Power = 2.0; // convergence curve power
15 PP1 = 1.0; // first iteration convergence factor
16
17 ArrayResize (params, 4);
18
19 params [0].name = "popSize"; params [0].val = popSize;
20 params [1].name = "Re"; params [1].val = Re;
21 params [2].name = "Power"; params [2].val = Power;
22 params [3].name = "PP1"; params [3].val = PP1;
23 }
24
25 void SetParams (void)
26 {
27 popSize = (int)params [0].val;
28 Re = (int)params [1].val;
29 Power = params [2].val;
30 PP1 = params [3].val;
31
32 // Check the parameters validity
33 if (Re < 0) Re = 0;
34 if (PP1 < 0.0) PP1 = 0.0;
35 if (PP1 > 1.0) PP1 = 1.0;
36 if (Power < 0.1) Power = 0.1;
37 }
38
39 bool Init (const double &rangeMinP [], // minimum values
40 const double &rangeMaxP [], // maximum values
41 const double &rangeStepP [], // step change
42 const int epochsP = 0); // number of epochs
43
44 void Moving (void);
45 void Revision (void);
46
47 //------------------------------------------------------------------
48 int Re; // effective search radius
49 double Power; // convergence curve power
50 double PP1; // first iteration convergence factor
51
52 private: //---------------------------------------------------------
53 double PP; // predetermined probability for the current iteration
54 int currentEpoch; // current epoch
55 int totalEpochs; // total number of epochs
56 double coeffA; // dynamic coefficient used to select positions
57
58 S_Coordinate coordData []; // coordinate data (alternatives and AF)
59
60 void CalculatePP (void);
61 void CalculateAccumulativeFitness (void);
62 void ResetAFforBestLocation (void);
63 void SelectNextLocations (void);
64 int FindNearestAlternative (int coord, double value);
65 void CalculateCoefficientA (void);
66};
67//————————————————————————————————————————————————————————————————————The Init method of the C_AO_DEA class serves to initialize the DEA algorithm. It takes as input the minimum and maximum values for each variable, the step changes for each variable, and the total number of epochs for optimization.
First, the method calls the base StandardInit method to perform standard initialization of common algorithm parameters, and if this initialization fails, it returns false. Then, variables tracking the current and total epochs for the algorithm's execution are initialized.
Next, the coordData data structure is created to store information about each coordinate (variable) of the search space. For each coordinate, the number of possible alternative values is determined.
If a step change is defined for a coordinate, the number of alternatives is calculated based on the boundaries and the step. If no step is specified (equal to zero), the coordinate is considered continuous, and a fixed number of alternatives is set for it.
Then, the Re (search radius) parameter is checked and, if necessary, adjusted so that it does not exceed one-quarter of the number of alternatives for each coordinate. After this, memory is allocated to store alternative values for each coordinate.
Finally, a loop populates the array of alternative values for each coordinate, distributing them uniformly between the minimum and maximum values. If a step is defined, alternative values are calculated using this step.
If no step is specified, spatial discretization between the given boundaries is applied. Also, for each alternative, its associated AF (accumulated fitness) value is initialized to zero.
If all initialization steps are completed successfully, the method returns true.
1//————————————————————————————————————————————————————————————————————
2//--- Initialization
3bool C_AO_DEA::Init (const double &rangeMinP [],
4 const double &rangeMaxP [],
5 const double &rangeStepP [],
6 const int epochsP = 0)
7{
8 if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
9
10 //------------------------------------------------------------------
11 currentEpoch = 0;
12 totalEpochs = epochsP;
13
14 // Initialize the data structure for coordinates
15 ArrayResize (coordData, coords);
16
17 // Create alternatives for each coordinate
18 for (int c = 0; c < coords; c++)
19 {
20 if (rangeStep [c] != 0)
21 {
22 coordData [c].count = (int)((rangeMax [c] - rangeMin [c]) / rangeStep [c]) + 1;
23 }
24 else
25 {
26 coordData [c].count = 500;
27 }
28
29 // Check that Re is not too large for the number of alternatives
30 if (Re > coordData [c].count / 4) Re = coordData [c].count / 4;
31
32 ArrayResize (coordData [c].alt, coordData [c].count);
33
34 // Fill in the alternatives
35 for (int i = 0; i < coordData [c].count; i++)
36 {
37 if (rangeStep [c] != 0)
38 {
39 coordData [c].alt [i].value = rangeMin [c] + i * rangeStep [c];
40 }
41 else
42 {
43 coordData [c].alt [i].value = rangeMin [c] + (rangeMax [c] - rangeMin [c]) * i / (coordData [c].count - 1);
44 }
45 coordData [c].alt [i].AF = 0.0;
46 }
47 }
48
49 return true;
50}
51//————————————————————————————————————————————————————————————————————The Moving method implements one core step of the DEA algorithm, corresponding to a specific iteration of the optimization process. If it's the first iteration, indicated by the revision flag, an initial random assignment of coordinates to the population occurs.
For each population member and for each variable within the specified range, random values are assigned. These values are adjusted to respect the boundaries and step of change to ensure valid solutions.
After this, the revision flag is set to true, indicating the completion of initialization, and the method finishes this part of the cycle.
After initialization, the current epoch (iteration) counter is incremented. Then, key algorithm steps are executed: performance metrics are determined for each solution in the current population, indicating how well they meet the task's criteria.
The dynamic "a" coefficient is calculated. Based on quality indicators, a generalized fitness measure is determined for each solution, and its "AF" index is reset, allowing the search to focus on the area of best solutions.
Based on current information and calculated coefficients, the next locations (positions) are chosen to update and move candidate solutions within the search space.
In short, the Moving method implements one iterative cycle of the DEA algorithm, sequentially performing key steps of updating and improving solutions in the process of finding the optimum.
1//————————————————————————————————————————————————————————————————————
2//--- The main step of the algorithm (according to Algorithm 1)
3void C_AO_DEA::Moving (void)
4{
5 // Initial setup
6 if (!revision)
7 {
8 for (int p = 0; p < popSize; p++)
9 {
10 for (int c = 0; c < coords; c++)
11 {
12 a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
13 a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
14 a [p].cB [c] = a [p].c [c];
15 }
16 }
17
18 revision = true;
19 return;
20 }
21
22 // Increase the epoch counter
23 currentEpoch++;
24
25 // Steps of the DEA algorithm according to Algorithm 1:
26
27 // 1. Calculate PP for the current iteration
28 CalculatePP ();
29
30 // 2. We calculate the 'a' dynamic coefficient
31 CalculateCoefficientA ();
32
33 // 3. Calculate accumulated fitness
34 CalculateAccumulativeFitness ();
35
36 // 4. Find the best location and reset AF for it
37 ResetAFforBestLocation ();
38
39 // 5. Select the next positions
40 SelectNextLocations ();
41}
42//————————————————————————————————————————————————————————————————————The CalculatePP method computes the predetermined probability (PP) used in the decision-making process within the algorithm. If the total number of epochs (iterations) is one or less, the probability is set equal to the predefined initial value (PP1). In this case, no further calculations are needed, and the method exits.
If the number of epochs is greater than one, the PP value is calculated based on a given formula that accounts for the current epoch and includes the following logic: a power, representing a function of the current epoch raised to the Power, is calculated, and one is subtracted from this value; similarly, the power for the total number of epochs is calculated.
The PP value is updated by a formula that gradually approaches 1, considering the current progress through the epochs. Specifically, a portion proportional to the progress, adjusted by a power function and the specified Power and totalEpochs parameters, is added to the initial PP1 value. If the overall power exponent is not zero, division occurs to obtain the current probability; otherwise, the value remains equal to the initial PP1.
Ultimately, the method dynamically alters the probability value during the algorithm's execution, balancing initial and more "progressive" values as epochs pass.
1//————————————————————————————————————————————————————————————————————
2//--- Calculate the predetermined probability (according to the formula 5)
3void C_AO_DEA::CalculatePP (void)
4{
5 if (totalEpochs <= 1)
6 {
7 PP = PP1;
8 return;
9 }
10
11 // PP = PP1 + (1 - PP1) * ((Loop^Power - 1) / (LoopsNumber^Power - 1))
12 double iterPower = MathPow ((double)currentEpoch, Power) - 1.0;
13 double totalPower = MathPow ((double)totalEpochs, Power) - 1.0;
14
15 if (totalPower != 0)
16 {
17 PP = PP1 + (1.0 - PP1) * iterPower / totalPower;
18 }
19 else
20 {
21 PP = PP1;
22 }
23}
24//————————————————————————————————————————————————————————————————————CalculateCoefficientA calculates the dynamic coefficient 'a', used to regulate the search process. The method iterates through the entire current population of solutions, and for each solution, it calculates the difference between the maximum possible fitness fB and the current fitness of that particular solution (a[i].f). These differences are accumulated into a total sum.
After accumulating the sum of values, the coefficient 'a' is obtained as the ratio of the difference between fB and the minimum fitness fW to the obtained sum. This allows for the determination of a dynamic coefficient that adapts based on the current state of the population and helps balance the convergence rate or exploration of the search space.
Thus, this method creates a scaling parameter that considers the distribution of solution fitness and influences their update and movement strategy in subsequent algorithm iterations.
1//————————————————————————————————————————————————————————————————————
2//--- Calculate the dynamic 'a' coefficient
3void C_AO_DEA::CalculateCoefficientA (void)
4{
5 double sumFitness = 0.0;
6
7 for (int i = 0; i < popSize; i++)
8 {
9 sumFitness += fB - a [i].f;
10 }
11
12 coeffA = (fB - fW) / sumFitness;
13}
14//————————————————————————————————————————————————————————————————————The FindNearestAlternative method is designed to locate the closest alternative to a given value within a specific coordinate. It takes two arguments: the coordinate index coord and the value for which the nearest alternative is to be found. Initial values for nearest (the index of the nearest alternative) and minDist (minimum distance) are initialized and set.
The loop iterates through all alternatives associated with the specified coordinate coord. For each alternative, the distance between the given value and the alternative's value (coordData[coord].alt[i].value) is calculated. If the calculated distance is less than the current minimum distance (minDist), then minDist is updated with the new, smaller distance value, and nearest is updated with the index of the current alternative.
Upon completion of the loop, the index of the alternative that was closest to the given value within the specified coordinate is returned. Thus, the method determines which of the available alternatives for the given coordinate most closely matches the given real value.
1//————————————————————————————————————————————————————————————————————
2//--- Search for the closest alternative
3int C_AO_DEA::FindNearestAlternative (int coord, double value)
4{
5 int nearest = 0;
6 double minDist = DBL_MAX;
7
8 for (int i = 0; i < coordData [coord].count; i++)
9 {
10 double dist = MathAbs (value - coordData [coord].alt [i].value);
11 if (dist < minDist)
12 {
13 minDist = dist;
14 nearest = i;
15 }
16 }
17
18 return nearest;
19}
20//————————————————————————————————————————————————————————————————————The CalculateAccumulativeFitness method is designed to compute the Accumulated Fitness (AF) for alternatives according to Algorithm 2. Before computation begins, all accumulated fitness values for each alternative in each coordinate are cleared and set to zero. The range of fitness values in the current solution population is determined, calculated as the difference between the maximum possible fitness (fB) and the minimum (fW).
Then, for each agent (dolphin), its fitness is normalized relative to this range. For each search coordinate, the nearest alternative is identified, and within a radius "Re" around this alternative, the accumulated fitness for the alternative is updated, accounting for the reflective nature of the boundaries. This is done by adding weighted contributions, where weights are formed based on the distance from the nearest alternative (considering reflective boundaries) and include a coefficient related to the current step within the "Re" radius.
As a result of this method's operation, accumulated fitness values are generated for each alternative in each coordinate, taking into account the contributions of neighboring alternatives.
1//————————————————————————————————————————————————————————————————————
2//--- Calculate the accumulated fitness (according to Algorithm 2)
3void C_AO_DEA::CalculateAccumulativeFitness (void)
4{
5 // Clear the accumulated fitness for all alternatives
6 for (int c = 0; c < coords; c++)
7 {
8 for (int i = 0; i < coordData [c].count; i++)
9 {
10 coordData [c].alt [i].AF = 0.0;
11 }
12 }
13
14 double rangeFF = fB - fW;
15 if (rangeFF == 0.0) rangeFF = DBL_EPSILON;
16
17 // For each agent (dolphin)
18 for (int i = 0; i < popSize; i++)
19 {
20 // Normalize 'fitness' for this agent
21 double normalizedFitness = (a [i].f - fW) / rangeFF;
22
23 for (int c = 0; c < coords; c++)
24 {
25 // Find the closest alternative for the current coordinate
26 int nearestAlt = FindNearestAlternative (c, a [i].c [c]);
27
28 // Update the accumulated fitness in Re radius
29 // According to Algorithm 2: AF(A+k)j = (1/Re) * (Re - |k|) * fitness(i) + AF(A+k)j
30 for (int k = -Re; k <= Re; k++)
31 {
32 int altIndex = nearestAlt + k;
33
34 // Boundary check taking into account reflection (reflective characteristic)
35 if (altIndex < 0)
36 {
37 altIndex = -altIndex; // reflection from the lower border
38 }
39 else if (altIndex >= coordData [c].count)
40 {
41 altIndex = 2 * (coordData [c].count - 1) - altIndex; // reflection from the upper border
42 }
43
44 if (altIndex >= 0 && altIndex < coordData [c].count)
45 {
46 double weight = (1.0 / (double)(Re + 1)) * (Re - MathAbs (k) + 1);
47 coordData [c].alt [altIndex].AF += weight * normalizedFitness;
48 }
49 }
50 }
51 }
52
53 // Add a small epsilon value to all AFs to avoid zero probabilities
54 double epsilon = 0.0001;
55 for (int c = 0; c < coords; c++)
56 {
57 for (int i = 0; i < coordData [c].count; i++)
58 {
59 coordData [c].alt [i].AF += epsilon;
60 }
61 }
62}
63//————————————————————————————————————————————————————————————————————The ResetAFforBestLocation method is designed to reset the Accumulated Fitness (AF) for alternatives corresponding to the location of the best solution (agent) in the population. First, the method determines the index of the best solution (agent) in the current population.
It iterates through all solutions, finding the solution with the maximum fitness value. The index of the solution with the highest fitness is stored in the bestIndex variable.
For each coordinate c of the best solution, the method identifies the nearest alternative to the best solution's coordinate value for that coordinate, using the FindNearestAlternative function. If the found alternative exists (the index is within a valid range), the Accumulated Fitness (AF) value for this specific alternative is reset to zero.
Thus, the method nullifies AF only for those alternatives that most closely match the coordinates of the best solution. This is done to reduce the influence of these alternatives on subsequent search stages, potentially encouraging the exploration of other areas of the search space.
As a result, the fitness of those coordinates that best correspond to the best solution is "zeroed out/reset" to stimulate the search for other, possibly more optimal solutions.
1//————————————————————————————————————————————————————————————————————
2//--- Reset AF for the best location (according to Algorithm 3)
3void C_AO_DEA::ResetAFforBestLocation (void)
4{
5 // Find the index of the best solution
6 int bestIndex = 0;
7 double bestFitness = a [0].f;
8
9 // Search for a solution with maximum fitness (since we always maximize normalized fitness)
10 for (int i = 1; i < popSize; i++)
11 {
12 if (a [i].f > bestFitness)
13 {
14 bestFitness = a [i].f;
15 bestIndex = i;
16 }
17 }
18
19 // Reset AF for ALL alternatives corresponding to the coordinates of the best solution
20 for (int c = 0; c < coords; c++)
21 {
22 // Find the closest alternative to the coordinate of the best solution
23 int nearestAlt = FindNearestAlternative (c, a [bestIndex].c [c]);
24
25 // Reset AF only for this alternative
26 if (nearestAlt >= 0 && nearestAlt < coordData [c].count)
27 {
28 coordData [c].alt [nearestAlt].AF = 0.0;
29 }
30 }
31}
32//————————————————————————————————————————————————————————————————————The SelectNextLocations method is designed to choose the next position for each solution in the population (for each dolphin) based on probabilistic considerations and taking into account both accumulated fitness (AF) and the strategy of preserving the best position. The method first identifies the best solution in the current population based on its fitness value. The index of the best solution is saved for future use.
For each solution and each of its coordinates, the following set of actions is performed: if the current solution is the best, and a random number is less than the probability PP, the current coordinate of this solution remains unchanged. This allows the previous best solution to be preserved.
However, if the current solution is not the best, or if its position is not retained according to PP, then all AF values for alternatives along the current coordinate are summed. If the total AF sum is greater than a small number (epsilon), indicating the presence of non-zero fitness values, a "roulette wheel" is performed: a random number proportional to the AF sum is selected, and the solution's coordinate is chosen based on the cumulative sum of AFs of the alternatives, which allows solutions to move towards locations with greater fitness.
If the AF sum is close to zero (all AF values are very small), a local search is performed if a random number is less than the dynamic coefficient coeffA. In this case, a random offset (-Re...+Re) relative to the current value is chosen, and the coordinate is updated to the nearest value. Boundaries are taken into account during this process.
A global search (random selection) is performed if a random number is greater than coeffA. In this case, a completely random alternative is selected for the coordinate. At the end of the method, the obtained coordinate value is constrained within the allowed range (rangeMin, rangeMax) and discretized with the specified rangeStep to ensure the value is within the valid range and corresponds to allowed values.
As a result of this method, the coordinates of each solution are updated considering probabilistic weights based on accumulated fitness, the PP strategy (preserving the best), and dynamic local and global search, allowing the algorithm to effectively explore the search space and find optimal solutions.
1//————————————————————————————————————————————————————————————————————
2//--- Select next positions based on probabilities
3void C_AO_DEA::SelectNextLocations (void)
4{
5 // First we find the index of the best solution
6 int bestIndex = 0;
7 double bestFitness = a [0].f;
8
9 for (int i = 1; i < popSize; i++)
10 {
11 if (a [i].f > bestFitness)
12 {
13 bestFitness = a [i].f;
14 bestIndex = i;
15 }
16 }
17
18 for (int i = 0; i < popSize; i++)
19 {
20 for (int c = 0; c < coords; c++)
21 {
22 // For the best agent, apply PP
23 if (i == bestIndex && u.RNDprobab < PP)
24 {
25 // Save the current value of the coordinate of the best solution with PP probability
26 continue;
27 }
28
29 // Select based on accumulated fitness
30 double totalAF = 0.0;
31 for (int alt = 0; alt < coordData [c].count; alt++)
32 {
33 totalAF += coordData [c].alt [alt].AF;
34 }
35
36 if (totalAF > DBL_EPSILON) // Check that there are non-zero AFs
37 {
38 // Choose an alternative based on roulette
39 double rnd = u.RNDprobab * totalAF;
40 double cumSum = 0.0;
41
42 for (int alt = 0; alt < coordData [c].count; alt++)
43 {
44 cumSum += coordData [c].alt [alt].AF;
45 if (cumSum >= rnd)
46 {
47 a [i].c [c] = coordData [c].alt [alt].value;
48 break;
49 }
50 }
51 }
52 else
53 {
54 // If all AFs are almost zero, use random selection
55 // with the dynamic coeffA coefficient for the local search probability
56 if (u.RNDprobab < coeffA) // Use the dynamic coefficient
57 {
58 // Local search - stay close to the current position
59 int currentAlt = FindNearestAlternative (c, a [i].c [c]);
60 int shift = u.RNDminusOne (2 * Re + 1) - Re; // random offset within Re
61 int newAlt = currentAlt + shift;
62
63 // Check boundaries
64 if (newAlt < 0) newAlt = 0;
65 if (newAlt >= coordData [c].count) newAlt = coordData [c].count - 1;
66
67 a [i].c [c] = coordData [c].alt [newAlt].value;
68 }
69 else
70 {
71 // Global search - completely random selection
72 int randAlt = u.RNDminusOne (coordData [c].count);
73 a [i].c [c] = coordData [c].alt [randAlt].value;
74 }
75 }
76
77 // Bounds checking and discretization
78 a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
79 }
80 }
81}
82//————————————————————————————————————————————————————————————————————The Revision method is used to update information about the best and worst solutions in the current population. The index of the best solution is identified, and the variable storing the best fitness is assigned the value of the worst among the current ones.
This establishes an initial state for searching for new extrema. All solutions in the current population are then searched: the solution with the maximum fitness value (the best solution) is identified.
Its value is stored, and the saved index is updated. The solution with the minimum fitness value (the worst solution) is also sought.
If a better solution is indeed found, its coordinates are copied into a special array or variable designated for storing the current best solution.
As a result of this method's execution, the coordinates of the best and worst solutions in the population are precisely known at the current time. This allows the algorithm to track the dynamics of the search and use this data in decision-making to more effectively find optimal solutions.
1//————————————————————————————————————————————————————————————————————
2//--- Update the best solution
3void C_AO_DEA::Revision (void)
4{
5 int bestIND = -1;
6 fW = fB;
7
8 // Find the best and worst solutions in the current population
9 for (int i = 0; i < popSize; i++)
10 {
11 // Update the best solution
12 if (a [i].f > fB)
13 {
14 fB = a [i].f;
15 bestIND = i;
16 }
17
18 // Update the worst solution
19 if (a [i].f < fW)
20 {
21 fW = a [i].f;
22 }
23 }
24
25 // Copy the coordinates of the best solution
26 if (bestIND != -1)
27 {
28 ArrayCopy (cB, a [bestIND].c, 0, 0, WHOLE_ARRAY);
29 }
30}
31//————————————————————————————————————————————————————————————————————Test Results
Now let's examine the obtained results. It can be immediately noted that the algorithm handles various types of tasks effectively and quickly.
1DEA|Dolphin Echolocation Algorithm|100.0|2.0|2.0|1.0|
2
3=============================
45 Hilly's; Func runs: 10000; result: 0.7599517883429889
525 Hilly's; Func runs: 10000; result: 0.6757192867862007
6500 Hilly's; Func runs: 10000; result: 0.34170057553968197
7=============================
85 Forest's; Func runs: 10000; result: 0.8958173952258406
925 Forest's; Func runs: 10000; result: 0.6422393144820473
10500 Forest's; Func runs: 10000; result: 0.23940903266305935
11=============================
125 Megacity's; Func runs: 10000; result: 0.6153846153846154
1325 Megacity's; Func runs: 10000; result: 0.4403076923076923
14500 Megacity's; Func runs: 10000; result: 0.15115384615384736
15=============================
16All score: 4.76168 (52.91%)The visualization demonstrates a spread of results for low-dimensional functions (green color) and good results for medium-dimensional functions (blue color).
<image>DEA on Hilly test function
<image>DEA on Forest test function
<image>DEA on Megacity test function
According to the results, the DEA algorithm ranks 25th in the rating table.
| # | 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) | |||
| 1 | ANS | across neighbourhood search | 0.94948 | 0.84776 | 0.43857 | 2.23581 | 1.00000 | 0.92334 | 0.39988 | 2.32323 |
| 2 | CLA | code lock algorithm (joo) | 0.95345 | 0.87107 | 0.37590 | 2.20042 | 0.98942 | 0.91709 | 0.31642 | 2.22294 |
| 3 | AMOm | animal migration ptimization M | 0.90358 | 0.84317 | 0.46284 | 2.20959 | 0.99001 | 0.92436 | 0.46598 | 2.38034 |
| 4 | (P+O)ES | (P+O) evolution strategies | 0.92256 | 0.88101 | 0.40021 | 2.20379 | 0.97750 | 0.87490 | 0.31945 | 2.17185 |
| 5 | CTA | comet tail algorithm (joo) | 0.95346 | 0.86319 | 0.27770 | 2.09435 | 0.99794 | 0.85740 | 0.33949 | 2.19484 |
| 6 | TETA | time evolution travel algorithm (joo) | 0.91362 | 0.82349 | 0.31990 | 2.05701 | 0.97096 | 0.89532 | 0.29324 | 2.15952 |
| 7 | SDSm | stochastic diffusion search M | 0.93066 | 0.85445 | 0.39476 | 2.17988 | 0.99983 | 0.89244 | 0.19619 | 2.08846 |
| 8 | BOAm | billiards optimization algorithm M | 0.95757 | 0.82599 | 0.25235 | 2.03590 | 1.00000 | 0.90036 | 0.30502 | 2.20538 |
| 9 | AAm | archery algorithm M | 0.91744 | 0.70876 | 0.42160 | 2.04780 | 0.92527 | 0.75802 | 0.35328 | 2.03657 |
| 10 | ESG | evolution of social groups (joo) | 0.99906 | 0.79654 | 0.35056 | 2.14616 | 1.00000 | 0.82863 | 0.13102 | 1.95965 |
| 11 | SIA | simulated isotropic annealing (joo) | 0.95784 | 0.84264 | 0.41465 | 2.21513 | 0.98239 | 0.79586 | 0.20507 | 1.98332 |
| 12 | BBO | biogeography based optimization | 0.94912 | 0.69456 | 0.35031 | 1.99399 | 0.93820 | 0.67365 | 0.25682 | 1.86867 |
| 13 | ACS | artificial cooperative search | 0.75547 | 0.74744 | 0.30407 | 1.80698 | 1.00000 | 0.88861 | 0.22413 | 2.11274 |
| 14 | DA | dialectical algorithm | 0.86183 | 0.70033 | 0.33724 | 1.89940 | 0.98163 | 0.72772 | 0.28718 | 1.99653 |
| 15 | BHAm | black hole algorithm M | 0.75236 | 0.76675 | 0.34583 | 1.86493 | 0.93593 | 0.80152 | 0.27177 | 2.00923 |
| 16 | ASO | anarchy society optimization | 0.84872 | 0.74646 | 0.31465 | 1.90983 | 0.96148 | 0.79150 | 0.23803 | 1.99101 |
| 17 | RFO | royal flush optimization (joo) | 0.83361 | 0.73742 | 0.34629 | 1.91733 | 0.89424 | 0.73824 | 0.24098 | 1.87346 |
| 18 | AOSm | atomic orbital search M | 0.80232 | 0.70449 | 0.31021 | 1.81702 | 0.85660 | 0.69451 | 0.21996 | 1.77107 |
| 19 | TSEA | turtle shell evolution algorithm (joo) | 0.96798 | 0.64480 | 0.29672 | 1.90949 | 0.99449 | 0.61981 | 0.22708 | 1.84139 |
| 20 | DE | differential evolution | 0.95044 | 0.61674 | 0.30308 | 1.87026 | 0.95317 | 0.78896 | 0.16652 | 1.90865 |
| 21 | SRA | successful restaurateur algorithm (joo) | 0.96883 | 0.63455 | 0.29217 | 1.89555 | 0.94637 | 0.55506 | 0.19124 | 1.69267 |
| 22 | CRO | chemical reaction optimization | 0.94629 | 0.66112 | 0.29853 | 1.90593 | 0.87906 | 0.58422 | 0.21146 | 1.67473 |
| 23 | BIO | blood inheritance optimization (joo) | 0.81568 | 0.65336 | 0.30877 | 1.77781 | 0.89937 | 0.65319 | 0.21760 | 1.77016 |
| 24 | BSA | bird swarm algorithm | 0.89306 | 0.64900 | 0.26250 | 1.80455 | 0.92420 | 0.71121 | 0.24939 | 1.88479 |
| 25 | DEA | dolphin_echolocation_algorithm | 0.75995 | 0.67572 | 0.34171 | 1.77738 | 0.89582 | 0.64223 | 0.23941 | 1.77746 |
| 26 | HS | harmony search | 0.86509 | 0.68782 | 0.32527 | 1.87818 | 0.99999 | 0.68002 | 0.09590 | 1.77592 |
| 27 | SSG | saplings sowing and growing | 0.77839 | 0.64925 | 0.39543 | 1.82308 | 0.85973 | 0.62467 | 0.17429 | 1.65869 |
| 28 | BCOm | bacterial chemotaxis optimization M | 0.75953 | 0.62268 | 0.31483 | 1.69704 | 0.89378 | 0.61339 | 0.22542 | 1.73259 |
| 29 | ABO | african buffalo optimization | 0.83337 | 0.62247 | 0.29964 | 1.75548 | 0.92170 | 0.58618 | 0.19723 | 1.70511 |
| 30 | (PO)ES | (PO) evolution strategies | 0.79025 | 0.62647 | 0.42935 | 1.84606 | 0.87616 | 0.60943 | 0.19591 | 1.68151 |
| 31 | FBA | Fractal-Based Algorithm | 0.79000 | 0.65134 | 0.28965 | 1.73099 | 0.87158 | 0.56823 | 0.18877 | 1.62858 |
| 32 | TSm | tabu search M | 0.87795 | 0.61431 | 0.29104 | 1.78330 | 0.92885 | 0.51844 | 0.19054 | 1.63783 |
| 33 | BSO | brain storm optimization | 0.93736 | 0.57616 | 0.29688 | 1.81041 | 0.93131 | 0.55866 | 0.23537 | 1.72534 |
| 34 | WOAm | wale optimization algorithm M | 0.84521 | 0.56298 | 0.26263 | 1.67081 | 0.93100 | 0.52278 | 0.16365 | 1.61743 |
| 35 | AEFA | artificial electric field algorithm | 0.87700 | 0.61753 | 0.25235 | 1.74688 | 0.92729 | 0.72698 | 0.18064 | 1.83490 |
| 36 | AEO | artificial ecosystem-based optimization algorithm | 0.91380 | 0.46713 | 0.26470 | 1.64563 | 0.90223 | 0.43705 | 0.21400 | 1.55327 |
| 37 | CAm | camel algorithm M | 0.78684 | 0.56042 | 0.35133 | 1.69859 | 0.82772 | 0.56041 | 0.24336 | 1.63149 |
| 38 | ACOm | ant colony optimization M | 0.88190 | 0.66127 | 0.30377 | 1.84693 | 0.85873 | 0.58680 | 0.15051 | 1.59604 |
| 39 | CMAES | covariance_matrix_adaptation_evolution_strategy | 0.76258 | 0.72089 | 0.00000 | 1.48347 | 0.82056 | 0.79616 | 0.00000 | 1.61672 |
| 40 | BFO-GA | bacterial foraging optimization - ga | 0.89150 | 0.55111 | 0.31529 | 1.75790 | 0.96982 | 0.39612 | 0.06305 | 1.42899 |
| 41 | SOA | simple optimization algorithm | 0.91520 | 0.46976 | 0.27089 | 1.65585 | 0.89675 | 0.37401 | 0.16984 | 1.44060 |
| 42 | ABHA | artificial bee hive algorithm | 0.84131 | 0.54227 | 0.26304 | 1.64663 | 0.87858 | 0.47779 | 0.17181 | 1.52818 |
| 43 | ACMO | atmospheric cloud model optimization | 0.90321 | 0.48546 | 0.30403 | 1.69270 | 0.80268 | 0.37857 | 0.19178 | 1.37303 |
| 44 | ADAMm | adaptive moment estimation M | 0.88635 | 0.44766 | 0.26613 | 1.60014 | 0.84497 | 0.38493 | 0.16889 | 1.39880 |
| 45 | CGO | chaos game optimization | 0.57256 | 0.37158 | 0.32018 | 1.26432 | 0.61176 | 0.61931 | 0.62161 | 1.85267 |
| RW | random walk | 0.48754 | 0.32159 | 0.25781 | 1.06694 | 0.37554 | 0.21944 | 0.15877 | 0.75375 |
Summary
The main advantages of the algorithm are: adaptive search control: the predetermined probability gradually increases, shifting the balance from exploration to exploitation; dynamic adaptation; collective memory: accumulated fitness stores and propagates information about promising areas; diversity mechanism: resetting information for the best positions encourages exploration of new areas.
The algorithm's strength lies in its adaptability. The dynamic coefficient makes the algorithm sensitive to the population's state and adjusts it to the rhythm of the task.
When dolphins are scattered across the search space, the algorithm encourages local exploration. However, when they begin to converge on a target, it pushes them towards new horizons, preventing them from getting stuck in the illusion of local success.
Accumulated fitness is the collective memory of the pod, where each discovery leaves an echo in the solution space. But unlike simple accumulation, the algorithm knows how to forget: nullifying the best positions paradoxically leads to even more significant discoveries.
This is not just a metaphor — it's a philosophy of optimization, where every click of the echolocator carries information about the space of possibilities.
<image>Figure 2. Color gradient of algorithms by corresponding tests
<image>Figure 3. Histogram of algorithm test results (scale from 0 to 100, higher is better, where 100 is the maximum possible theoretical result; a script for calculating the rating table is included in the archive)
Pros and Cons of DEA:
Pros:
- Good convergence on medium and high-dimensional functions.
- Small number of external parameters.
Cons:
- Some tendency to get stuck on low-dimensional problems.
- Resource-intensive on high-dimensional functions.
An archive containing the current versions of the algorithm codes is attached to the article. The author of the article is not responsible for the absolute accuracy in describing canonical algorithms.
Many of them have been modified to improve search capabilities. The conclusions and judgments presented in the articles are based on experimental results.
Programs used in the article
| # | Name | Type | Description |
|---|---|---|---|
| 1 | #C_AO.mqh | Include | Parent class for population optimization algorithms |
| 2 | #C_AO_enum.mqh | Include | Enumeration of population optimization algorithms |
| 3 | TestFunctions.mqh | Include | Library of test functions |
| 4 | TestStandFunctions.mqh | Include | Library of test stand functions |
| 5 | Utilities.mqh | Include | Library of helper functions |
| 6 | CalculationTestResults.mqh | Include | Script for calculating results in the comparison table |
| 7 | Testing AOs.mq5 | Script | Unified test stand for all population optimization algorithms |
| 8 | Simple use of population optimization algorithms.mq5 | Script | Simple example of using population optimization algorithms without visualization |
| 9 | Test_AO_DEA.mq5 | Script | DEA test stand |
Translated into Russian by MetaQuotes Ltd.
Original article: Dolphin Echolocation Algorithm (DEA)
Attached Files | Download ZIP (236.09 KB)
Attention: All rights to these materials belong to MetaQuotes Ltd. Copying or reprinting these materials in whole or in part is prohibited.
This article was written by a user of the site and reflects their personal opinion. MetaQuotes Ltd is not responsible for the accuracy of the information provided, or for any consequences arising from the use of the described solutions, strategies, or recommendations.
Andrey Dik
- Russia
- 71033
CONSIDERING OFFERS FOR PUBLISHING A BOOK (TEXTBOOK) ON OPTIMIZATION ALGORITHMS.
Group for communication about optimization and free product testing: t.me/+vazsAAcney4zYmZi
Beware! There are Telegram imposters; my real username is @JQS_aka_Joo
My GitHub with optimization algorithms: https://github.com/JQSakaJoo/Population-optimization-algorithms-MQL5
All my publications:
I have been developing systems based on machine learning technologies since 2007 in the fields of artificial intelligence, optimization, and forecasting.
Other articles by this author
- Covariance Matrix Adaptation Evolution Strategy (CMA-ES)
- Eagle Strategy (ES)
- Biogeography-Based Optimization (BBO)
- Deterministic Oscillatory Search (DOS)
- Camel Algorithm (CA)
- Fractal-Based Algorithm (FBA)
Go to discussion
Analyzing Price Time Gaps in MQL5 (Part I): Creating a Basic Indicator
Analyzing time gaps helps traders identify potential market reversal points. This article examines what a time gap is, how to interpret it, and how it can be used to detect large influxes of volume into the market.
Market Modeling (Part 21): First Steps in SQL (IV)
Many of you may have much more experience with databases than I do, and therefore may hold a different opinion. Since it was necessary to explain why databases are structured the way they are, and why SQL has its particular form — especially why primary and foreign keys exist — some things had to remain somewhat abstract.
From Basics to Advanced: Objects (I)
In this article, we will begin to consider how to work with objects directly on the chart. This is done using code specifically designed for demonstration purposes.
Working with objects is very interesting and can be a lot of fun. Since this will be our first contact with the topic, we will start with something very simple.
From Basics to Advanced: Indicator (V)
In this article, we will examine how to process user requests to change the chart display mode. This is necessary so that an indicator developed for the current chart display mode does not appear strange or deviate from what a MetaTrader 5 user expects.
\
Use your metatrader.com login\
\
Access our new hub for expert analysis, trading insights, global financial news, and more.\
\
Learn more
This website uses cookies. Learn more about our Cookie Policy.
You are missing out on trading opportunities:
- Free trading applications
- Over 8000 signals to copy
- Economic news for financial market research
Register
Log In
latin letters without spaces
password will be sent to this email address
An error occurred
- Log in with Google
You agree to the website policy and terms of use
If you don't have an account, please register
Please enable cookies to log in to the website.
<p style="text-align: left;">Please enable the necessary setting in your browser, otherwise you will not be able to log in.</p>Forgot login/password?
- Log in with Google
