Files
Population-optimization-alg…/MQL5/Include/Math/AOs/PopulationAO/AO_HS_HarmonySearch.mqh
T
2026-04-19 22:04:37 +04:00

184 lines
10 KiB
Plaintext

//+——————————————————————————————————————————————————————————————————+
//| C_AO_HS |
//| Copyright 2007-2025, Andrey Dik |
//| https://www.mql5.com/ru/users/joo |
//+——————————————————————————————————————————————————————————————————+
#include "#C_AO.mqh"
//————————————————————————————————————————————————————————————————————
class C_AO_HS : public C_AO
{
public: //------------------------------------------------------------
~C_AO_HS() { }
C_AO_HS()
{
ao_name = "HS";
ao_desc = "Harmony Search";
ao_link = "https://www.mql5.com/ru/articles/11230";
popSize = 50;
Eh = 0.9;
Ep = 0.1;
rangeKo = 0.1;
ArrayResize(params, 4);
params [0].name = "popSize";
params [0].val = popSize;
params [1].name = "Eh";
params [1].val = Eh;
params [2].name = "Ep";
params [2].val = Ep;
params [3].name = "rangeKo";
params [3].val = rangeKo;
}
void SetParams()
{
popSize = (int)params [0].val;
Eh = params [1].val;
Ep = params [2].val;
rangeKo = params [3].val;
}
bool Init(const double &rangeMinP [],
const double &rangeMaxP [],
const double &rangeStepP [],
const int epochsP = 0);
void Moving();
void Revision();
//------------------------------------------------------------------
double Eh; // частота случайного выбора аккорда из гармонии
double Ep; // частота пошаговой настройки
double rangeKo; // диапазон случайного отклонения
private: //-----------------------------------------------------------
int epochs;
int epochNow;
double freq []; // ширина диапазона по каждой координате
};
//————————————————————————————————————————————————————————————————————
//————————————————————————————————————————————————————————————————————
bool C_AO_HS::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(freq, coords);
for(int c = 0; c < coords; c++)
{
freq [c] = rangeMax [c] - rangeMin [c];
}
return true;
}
//————————————————————————————————————————————————————————————————————
//————————————————————————————————————————————————————————————————————
void C_AO_HS::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;
}
//--------------------------------------------------------------------
epochNow++;
double r = 0.0;
int addr = 0;
double minB = 0.0;
double maxB = 0.3;
double B = 0.0;
if(epochs > 0)
B = ((epochs - epochNow) / (double)epochs) * (maxB - minB) + minB;
else
B = maxB;
for(int i = 0; i < popSize; i++)
{
for(int c = 0; c < coords; c++)
{
r = u.RNDfromCI(0.0, 1.0);
if(r <= Eh)
{
// выбрать аккорд из случайной гармонии
r = u.RNDfromCI(0.0, popSize - 1);
addr = (int)MathRound(r);
if(addr < 0)
addr = 0;
if(addr > popSize - 1)
addr = popSize - 1;
a [i].c [c] = a [addr].cB [c];
// пошаговая настройка с вероятностью Ep
r = u.RNDfromCI(0.0, 1.0);
if(r < Ep)
{
r = u.RNDfromCI(-1.0, 1.0);
a [i].c [c] = a [i].c [c] + r * B * freq [c];
}
}
else
{
// случайное отклонение от личного лучшего
r = u.RNDfromCI(-1.0, 1.0);
a [i].c [c] = a [i].cB [c] + r * rangeKo * freq [c];
}
a [i].c [c] = u.SeInDiSp(a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
}
}
}
//————————————————————————————————————————————————————————————————————
//————————————————————————————————————————————————————————————————————
void C_AO_HS::Revision()
{
for(int i = 0; i < popSize; i++)
{
// обновление глобального лучшего
if(a [i].f > fB)
{
fB = a [i].f;
ArrayCopy(cB, a [i].c, 0, 0, WHOLE_ARRAY);
}
// обновление личного лучшего
if(a [i].f > a [i].fB)
{
a [i].fB = a [i].f;
ArrayCopy(a [i].cB, a [i].c, 0, 0, WHOLE_ARRAY);
}
}
}
//————————————————————————————————————————————————————————————————————