200 lines
12 KiB
Plaintext
200 lines
12 KiB
Plaintext
//+————————————————————————————————————————————————————————————————————————————+
|
|
//| C_AO_GWO |
|
|
//| Copyright 2007-2024, Andrey Dik |
|
|
//| https://www.mql5.com/ru/users/joo |
|
|
//—————————————————————————————————————————————————————————————————————————————+
|
|
|
|
//Article: https://www.mql5.com/ru/articles/11785
|
|
|
|
#include "#C_AO.mqh"
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
class C_AO_GWO : public C_AO
|
|
{
|
|
public: //--------------------------------------------------------------------
|
|
~C_AO_GWO () { }
|
|
C_AO_GWO ()
|
|
{
|
|
ao_name = "GWO";
|
|
ao_desc = "Grey Wolf Optimizer";
|
|
ao_link = "https://www.mql5.com/ru/articles/11785";
|
|
|
|
popSize = 50; //population size
|
|
alphaNumber = 10; //Alpha beta delta number
|
|
|
|
ArrayResize (params, 2);
|
|
|
|
params [0].name = "popSize"; params [0].val = popSize;
|
|
params [1].name = "alphaNumber"; params [1].val = alphaNumber;
|
|
}
|
|
|
|
void SetParams ()
|
|
{
|
|
popSize = (int)params [0].val;
|
|
alphaNumber = (int)params [1].val;
|
|
}
|
|
|
|
bool Init (const double &rangeMinP [], //minimum search range
|
|
const double &rangeMaxP [], //maximum search range
|
|
const double &rangeStepP [], //step search
|
|
const int epochsP = 0); //number of epochs
|
|
|
|
void Moving ();
|
|
void Revision ();
|
|
void Injection (const int popPos, const int coordPos, const double value);
|
|
|
|
//----------------------------------------------------------------------------
|
|
int alphaNumber; //Alpha beta delta number of all wolves
|
|
|
|
private: //-------------------------------------------------------------------
|
|
S_AO_Agent aT [];
|
|
|
|
void ReturnToRange (S_AO_Agent &wolf);
|
|
int epochCount;
|
|
int epochNow;
|
|
};
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
bool C_AO_GWO::Init (const double &rangeMinP [], //minimum search range
|
|
const double &rangeMaxP [], //maximum search range
|
|
const double &rangeStepP [], //step search
|
|
const int epochsP = 0) //number of epochs
|
|
{
|
|
if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
|
|
|
|
//----------------------------------------------------------------------------
|
|
epochCount = epochsP;
|
|
epochNow = 0;
|
|
|
|
ArrayResize (aT, popSize);
|
|
for (int i = 0; i < popSize; i++)
|
|
{
|
|
ArrayResize (aT [i].c, coords);
|
|
aT [i].f = -DBL_MAX;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
void C_AO_GWO::Moving ()
|
|
{
|
|
epochNow++;
|
|
//----------------------------------------------------------------------------
|
|
//space has not been explored yet, then send the wolf in a random direction
|
|
if (!revision)
|
|
{
|
|
for (int w = 0; w < popSize; w++)
|
|
{
|
|
for (int c = 0; c < coords; c++)
|
|
{
|
|
a [w].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
|
|
a [w].c [c] = u.SeInDiSp (a [w].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
|
}
|
|
}
|
|
|
|
revision = true;
|
|
return;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double aKo = sqrt (2.0 * (1.0 - (epochNow / epochCount)));
|
|
double r1 = 0.0;
|
|
double r2 = 0.0;
|
|
|
|
double Ai = 0.0;
|
|
double Ci = 0.0;
|
|
double Xn = 0.0;
|
|
|
|
double min = 0.0;
|
|
double max = 1.0;
|
|
|
|
//amega-----------------------------------------------------------------------
|
|
for (int w = alphaNumber; w < popSize; w++)
|
|
{
|
|
Xn = 0.0;
|
|
|
|
for (int c = 0; c < coords; c++)
|
|
{
|
|
for (int abd = 0; abd < alphaNumber; abd++)
|
|
{
|
|
r1 = u.RNDfromCI (min, max);
|
|
r2 = u.RNDfromCI (min, max);
|
|
Ai = 2.0 * aKo * r1 - aKo;
|
|
Ci = 2.0 * r2;
|
|
Xn += a [abd].c [c] - Ai * (Ci * a [abd].c [c] - a [w].c [c]);
|
|
}
|
|
|
|
a [w].c [c] = Xn /= (double)alphaNumber;
|
|
}
|
|
|
|
ReturnToRange (a [w]);
|
|
}
|
|
|
|
//alpha, beta, delta----------------------------------------------------------
|
|
for (int w = 0; w < alphaNumber; w++)
|
|
{
|
|
for (int c = 0; c < coords; c++)
|
|
{
|
|
r1 = u.RNDfromCI (min, max);
|
|
r2 = u.RNDfromCI (min, max);
|
|
|
|
Ai = 2.0 * aKo * r1 - aKo;
|
|
Ci = 2.0 * r2;
|
|
|
|
a [w].c [c] = cB [c] - Ai * (Ci * cB [c] - a [w].c [c]);
|
|
}
|
|
|
|
ReturnToRange (a [w]);
|
|
}
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
void C_AO_GWO::Revision ()
|
|
{
|
|
u.Sorting (a, aT, popSize);
|
|
|
|
if (a [0].f > fB)
|
|
{
|
|
fB = a [0].f;
|
|
ArrayCopy (cB, a [0].c, 0, 0, WHOLE_ARRAY);
|
|
}
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
void C_AO_GWO::ReturnToRange (S_AO_Agent &wolf)
|
|
{
|
|
for (int c = 0; c < coords; c++)
|
|
{
|
|
if (wolf.c [c] < rangeMin [c]) wolf.c [c] = rangeMax [c] - (rangeMin [c] - wolf.c [c]);
|
|
if (wolf.c [c] > rangeMax [c]) wolf.c [c] = rangeMin [c] + (wolf.c [c] - rangeMax [c]);
|
|
|
|
wolf.c [c] = u.SeInDiSp (wolf.c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
|
}
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————
|
|
void C_AO_GWO::Injection (const int popPos, const int coordPos, const double value)
|
|
{
|
|
if (popPos < 0 || popPos >= popSize) return;
|
|
if (coordPos < 0 || coordPos >= coords) return;
|
|
|
|
if (value < rangeMin [coordPos])
|
|
{
|
|
a [popPos].c [coordPos] = rangeMin [coordPos];
|
|
}
|
|
|
|
if (value > rangeMax [coordPos])
|
|
{
|
|
a [popPos].c [coordPos] = rangeMax [coordPos];
|
|
}
|
|
|
|
a [popPos].c [coordPos] = u.SeInDiSp (value, rangeMin [coordPos], rangeMax [coordPos], rangeStep [coordPos]);
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————
|