Files
Population-optimization-alg…/MQL5/Include/Math/AOs/PopulationAO/AO_SIA_SimulatedIsotropicAnnealing.mqh
T
JQSakaJoo 0d6e221821 add TSEA
2024-04-29 18:04:37 +05:00

209 lines
12 KiB
Plaintext

//+————————————————————————————————————————————————————————————————————————————+
//| C_AO_SIA |
//| Copyright 2007-2024, Andrey Dik |
//| https://www.mql5.com/ru/users/joo |
//—————————————————————————————————————————————————————————————————————————————+
//Article: https://www.mql5.com/ru/articles/13870
//
#include "#C_AO.mqh"
//——————————————————————————————————————————————————————————————————————————————
struct S_SIA_Agent
{
void Init (int coords)
{
ArrayResize (cPrev, coords);
fPrev = -DBL_MAX;
}
double cPrev []; //previous coordinates
double fPrev; //previous fitness
};
//——————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————
class C_AO_SIA : public C_AO
{
public: //--------------------------------------------------------------------
~C_AO_SIA () { }
C_AO_SIA ()
{
ao_name = "SIA";
ao_desc = "Simulated Isotropic Annealing";
ao_link = "https://www.mql5.com/ru/articles/13870";
popSize = 100; //population size
T = 0.01; //Temperature
d = 0.1; //Diffusion coefficient
ArrayResize (params, 3);
params [0].name = "popSize"; params [0].val = popSize;
params [1].name = "T"; params [1].val = T;
params [2].name = "d"; params [2].val = d;
}
void SetParams ()
{
popSize = (int)params [0].val;
T = params [1].val;
d = params [2].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 ();
//----------------------------------------------------------------------------
double T; //Temperature
double d; //Diffusion coefficient
S_SIA_Agent agent [];
private: //-------------------------------------------------------------------
int epochs;
int epoch;
double Diffusion (const double value, const double rMin, const double rMax, const double step);
};
//——————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————
bool C_AO_SIA::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;
//----------------------------------------------------------------------------
epochs = epochsP;
epoch = 0;
ArrayResize (agent, popSize);
for (int i = 0; i < popSize; i++) agent [i].Init (coords);
return true;
}
//——————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————
void C_AO_SIA::Moving ()
{
//----------------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------------
int r = 0;
double rnd = 0.0;
for (int i = 0; i < popSize; i++)
{
for (int c = 0; c < coords; c++)
{
r = u.RNDminusOne (popSize);
if (agent [r].fPrev > agent [i].fPrev)
{
a [i].c [c] = agent [r].cPrev [c];
}
else
{
a [i].c [c] = agent [i].cPrev [c];
}
rnd = u.RNDfromCI (-0.1, 0.1);
a [i].c [c] = a [i].c [c] + rnd * (rangeMax [c] - rangeMin [c]) * d;
a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
}
}
}
//——————————————————————————————————————————————————————————————————————————————
//——————————————————————————————————————————————————————————————————————————————
void C_AO_SIA::Revision ()
{
//----------------------------------------------------------------------------
int ind = -1;
for (int i = 0; i < popSize; i++)
{
if (a [i].f > fB)
{
fB = a [i].f;
ind = i;
}
}
if (ind != -1) ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY);
epoch++;
//----------------------------------------------------------------------------
double maxD = -DBL_MAX;
double minD = DBL_MAX;
double maxF = -DBL_MAX;
double minF = DBL_MAX;
double ΔE;
double P;
for (int i = 0; i < popSize; i++)
{
ΔE = fabs (a [i].f - agent [i].fPrev);
if (ΔE > maxD) maxD = ΔE;
if (ΔE < minD) minD = ΔE;
if (a [i].f < minF) minF = a [i].f;
}
for (int i = 0; i < popSize; i++)
{
ΔE = fabs (a [i].f - agent [i].fPrev);
if (a [i].f > agent [i].fPrev)
{
agent [i].fPrev = a [i].f;
ArrayCopy (agent [i].cPrev, a [i].c, 0, 0, WHOLE_ARRAY);
}
else
{
//(1-0.1)*(acosh(-(x^3-3)))/1,765
double x = u.Scale (epoch, 1, epochs, 0, 1.3, false);
P = T *(1.0 - (ΔE / maxD)) * (acosh (-(pow (x, 3.0) - 3.0))) / 1.765;
if (u.RNDprobab () < P)
{
agent [i].fPrev = a [i].f;
ArrayCopy (agent [i].cPrev, a [i].c, 0, 0, WHOLE_ARRAY);
}
}
}
}
//——————————————————————————————————————————————————————————————————————————————