From af1c845dd83e75880f38702ca707c1d5ce5eedc1 Mon Sep 17 00:00:00 2001 From: JQSakaJoo Date: Tue, 9 Apr 2024 15:41:46 +0500 Subject: [PATCH] files --- MQL5/Include/Math/AOs/PopulationAO/#C_AO.mqh | Bin 0 -> 7472 bytes .../Math/AOs/PopulationAO/#C_AO_enum.mqh | Bin 0 -> 6546 bytes .../AO_BSA_BirdSwarmAlgorithm.mqh | 334 +++++++++++ .../AO_BSO_BrainStormOptimization.mqh | 557 ++++++++++++++++++ .../PopulationAO/AO_Boids_BoidsAlgorithm.mqh | Bin 0 -> 28034 bytes MQL5/Include/Math/AOs/TestFunctions.mqh | Bin 0 -> 41686 bytes MQL5/Include/Math/AOs/TestStandFunctions.mqh | Bin 0 -> 17460 bytes MQL5/Include/Math/AOs/Textures/checker.bmp | Bin 0 -> 196662 bytes MQL5/Include/Math/AOs/Utilities.mqh | Bin 0 -> 18320 bytes MQL5/Include/Math/AOs/desktop.ini | 4 + 10 files changed, 895 insertions(+) create mode 100644 MQL5/Include/Math/AOs/PopulationAO/#C_AO.mqh create mode 100644 MQL5/Include/Math/AOs/PopulationAO/#C_AO_enum.mqh create mode 100644 MQL5/Include/Math/AOs/PopulationAO/AO_BSA_BirdSwarmAlgorithm.mqh create mode 100644 MQL5/Include/Math/AOs/PopulationAO/AO_BSO_BrainStormOptimization.mqh create mode 100644 MQL5/Include/Math/AOs/PopulationAO/AO_Boids_BoidsAlgorithm.mqh create mode 100644 MQL5/Include/Math/AOs/TestFunctions.mqh create mode 100644 MQL5/Include/Math/AOs/TestStandFunctions.mqh create mode 100644 MQL5/Include/Math/AOs/Textures/checker.bmp create mode 100644 MQL5/Include/Math/AOs/Utilities.mqh create mode 100644 MQL5/Include/Math/AOs/desktop.ini diff --git a/MQL5/Include/Math/AOs/PopulationAO/#C_AO.mqh b/MQL5/Include/Math/AOs/PopulationAO/#C_AO.mqh new file mode 100644 index 0000000000000000000000000000000000000000..b7c19b18e444083b1b280295664bf254f4862101 GIT binary patch literal 7472 zcmeHMYi}D>5S`CReCrQbQVGQhX`+gU)CW?U7O2!vD**ul6ghq*Tl@&#I8fU1(}8nl zJihm?cil}D6<4ZOwl{m{&hyM;Z~pyfM|NaOZe;6uZOMo70W{o^my)g3wJ*oACr_c% z%eSE8zD(p?p378nIh8ZHfZW@%i|Y&7*1OyCseFQ`doq?D==z|}JqYG$Q z$Q_N=AHwUFjO2G2%4fLi!h#XjrZU6#43vG`7r1|hl}V!GdSa1U86F*zH{sneEE~d} z9_-0vLvD&A<5<3jPjam0`rC)K=8-edk;n4>dvYKhP@l;!imn2`^<2JGF687It*_^9 zWYn>MZA3s9znL6q4h@0miL_z&6rYjW@}Y+M00BMCDdqt4gh(fp-^a?X)(28B zQe%w}b8CtxmT~be*M;?j$RzTn*p(qSi9qUocV20nwv4cV(E~`}s?9W}WfP1B4u_CO z4xSz4aWxJ^`7?0gyk;3z#=CowzGKWLkj99`_;Z?2`KsyC+_5=t2I*;ycF(0V-`AkK zkZA;GP^(+uO!_Tctwjx{{i$}r zV;LwZX*2O)E8)s)&XLczfJv*zTiCII_vf-Dp%+s^8awkru-s_rJ@?=_c1(Z;Lv0@w zd41*(*D;N28IOiE`)1wYdikv;_}(joaR~^l=Hlz@yyuIoUZoe`U&lB_NT-jWm#@b$ zNHdvei+dn7i>HCBcEEb>>{`p*uhz@zxF0E|*neW(8OiFd(&z@F2~(X#cKPVk|cvp28?#L@HlxatHWgB~$&!@*3a1tNh}geOk}(D7`< zCD|a41#JF1@qK@nVl*z7^ zzUkQ82q!Y08L$J!zT@6Dp1I!aPl0!gd1}LVtklcwY1=qOeIQRTF&v#{Z}9)1C-O+oK@a5+S^d+BnAb@SIEpQ~LtWXFHX_G=&UysTe8XKE^Pb?G!rBY@HbV4sv<_iAhClr|t5_XeXEiWU zG>cd&;@ffnMEi0_wxxrsZTSjh^aj!9z}oxMj z`aFhZ3%!=}+{7%FQ>Vz$4pt<2jA6anJc@IXoSp!$qA>oY9SML5#?4i2XoEpV~~G%Lp*{QZ$Ui9%gfd z++{N0i$~W(m1twU=VU$bQznM39x}WMe$IjW6dA`OHN#^IIg#g9f`oZ=fT!-yJyI9) z*iB~BT-uR0^InZ}4xPv^jlkh8*lvY>i)(W`_?y*Och$pC=LSF#=NEUg)m4Xh1?jcc z3+9mGF&{UAk6U2oF>jn#k=?+IJr|vvbun|TL*=zSM~!3!W&Iptb&YUG59O$w)B)~` z7xOqQeiEx$7m*lZ)&bToJ$({Zug-jNck%hn6N_i(?qF4hdSp`syOnXYj}; z_#p?QG)K4-+TOUV3dPZ4gsQ8DZe+yDSk16fxpS#1ru9dNJF_>|IMk?BI<#WPn#U2V z!ePdAg0`*(ZXzz%JdWH{MYX(5OLF>9=UoULs_+6Rw%uPCvMAayz}?+R5#)esXK9q1;;3QQnejDYwUZ%B`uUGJ8>1xt&~H zThXq2fNGa&<*BaGMyRQ-t(*(v;QGq#TCrSXS&K4N?R0Ox2XZxN3$>2g<4n^w>J-~= zF1A{RrlWP_9!BnAW{&zLs=4fIL?(B!gY}`&`p_oRfP?Q=wp(Y=Z+F5--?QVfN6<1l zBRNj+9?9`g4HkNHZo_9U8@jDN%6{UVz;60D$I5~GFFLClq#~J?Z$@W#mdfx`d z7igz8oI-D$Vg#ShuOw3_yd0>g8L1u>SB?=n#^%s}txUx|pKTWr#~R>r#A)xn=l z)LQ5M)z4|~)uJxe-558&s}4{hW~f}#LbceFcX-2pQ&JJU#pe2TUKM%IwO{4;slSE9 B#R32T literal 0 HcmV?d00001 diff --git a/MQL5/Include/Math/AOs/PopulationAO/AO_BSA_BirdSwarmAlgorithm.mqh b/MQL5/Include/Math/AOs/PopulationAO/AO_BSA_BirdSwarmAlgorithm.mqh new file mode 100644 index 0000000..7cdaea8 --- /dev/null +++ b/MQL5/Include/Math/AOs/PopulationAO/AO_BSA_BirdSwarmAlgorithm.mqh @@ -0,0 +1,334 @@ +//+————————————————————————————————————————————————————————————————————————————+ +//| C_AO_BSA | +//| Copyright 2007-2024, Andrey Dik | +//| https://www.mql5.com/ru/users/joo | +//—————————————————————————————————————————————————————————————————————————————+ + +#include "#C_AO.mqh" + +//—————————————————————————————————————————————————————————————————————————————— +struct S_BSA_Agent +{ + double cBest []; //best coordinates + double fBest; //best fitness + + void Init (int coords) + { + ArrayResize (cBest, coords); + fBest = -DBL_MAX; + } +}; +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +class C_AO_BSA : public C_AO +{ + public: //-------------------------------------------------------------------- + ~C_AO_BSA () { } + C_AO_BSA () + { + ao_name = "BSA"; + ao_desc = "Bird Swarm Algorithm"; + + popSize = 20; //population size + + flyingProb = 0.8; //Flight probability + producerProb = 0.25; //Producer probability + foragingProb = 0.55; //Foraging probability + a1 = 0.6; //a1 constant [0...2] + a2 = 0.05; //a2 constant [0...2] + C = 0.05; //Cognitive coefficient + S = 1.1; //Social coefficient + FL = 1.75; //FL constant [0...2] + producerPower = 7.05; //Producer power + scroungerPower = 2.60; //Scrounger power + + ArrayResize (params, 11); + + params [0].name = "popSize"; params [0].val = popSize; + + params [1].name = "flyingProb"; params [1].val = flyingProb; + params [2].name = "producerProb"; params [2].val = producerProb; + params [3].name = "foragingProb"; params [3].val = foragingProb; + params [4].name = "a1"; params [4].val = a1; + params [5].name = "a2"; params [5].val = a2; + params [6].name = "C"; params [6].val = C; + params [7].name = "S"; params [7].val = S; + params [8].name = "FL"; params [8].val = FL; + params [9].name = "producerPower"; params [9].val = producerPower; + params [10].name = "scroungerPower"; params [10].val = scroungerPower; + } + + void SetParams () + { + popSize = (int)params [0].val; + + flyingProb = params [1].val; + producerProb = params [2].val; + foragingProb = params [3].val; + a1 = params [4].val; + a2 = params [5].val; + C = params [6].val; + S = params [7].val; + FL = params [8].val; + producerPower = params [9].val; + scroungerPower = params [10].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); + + //---------------------------------------------------------------------------- + double flyingProb; //Flight probability + double producerProb; //Producer probability + double foragingProb; //Foraging probability + double a1; //a1 constant [0...2] + double a2; //a2 constant [0...2] + double C; //Cognitive coefficient + double S; //Social coefficient + double FL; //FL constant [0...2] + double producerPower; //Producer power + double scroungerPower; //Scrounger power + + S_BSA_Agent agent []; + + private: //------------------------------------------------------------------- + double mean []; //represents the element of the average position of the whole bird’s swarm + double N; + double e; //epsilon + + void BirdProducer (int pos); + void BirdScrounger (int pos); + void BirdForaging (int pos); + void BirdVigilance (int pos); +}; +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +bool C_AO_BSA::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; + + //---------------------------------------------------------------------------- + ArrayResize (agent, popSize); + for (int i = 0; i < popSize; i++) agent [i].Init (coords); + + ArrayResize (mean, coords); + + N = popSize; + e = DBL_MIN; + + return true; +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::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; + } + + //---------------------------------------------------------------------------- + for (int i = 0; i < popSize; i++) + { + //bird is flying------------------------------------------------------------ + if (u.RNDprobab () < flyingProb) + { + //bird producer + if (u.RNDprobab () < producerProb) BirdProducer (i); //bird is looking for a new place to eat + //bird is not a producer + else BirdScrounger (i); //scrounger follows the producer + } + //bird is not flying-------------------------------------------------------- + else + { + //bird foraging + if (u.RNDprobab () < foragingProb) BirdForaging (i); //bird feeds + //bird is not foraging + else BirdVigilance (i); //bird vigilance + } + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::Revision () +{ + //---------------------------------------------------------------------------- + int ind = -1; + + for (int i = 0; i < popSize; i++) + { + if (a [i].f > fB) ind = i; + } + + if (ind != -1) + { + fB = a [ind].f; + ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY); + } + + //---------------------------------------------------------------------------- + for (int i = 0; i < popSize; i++) + { + if (a [i].f > agent [i].fBest) + { + agent [i].fBest = a [i].f; + ArrayCopy (agent [i].cBest, a [i].c, 0, 0, WHOLE_ARRAY); + } + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::BirdProducer (int pos) +{ + double x = 0.0; //bird position + + for (int c = 0; c < coords; c++) + { + x = a [pos].c [c]; + x = u.GaussDistribution (x, rangeMin [c], rangeMax [c], producerPower); + + a [pos].c [c] = u.SeInDiSp (x, rangeMin [c], rangeMax [c], rangeStep [c]); + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::BirdScrounger (int pos) +{ + int K = 0; //position of a randomly selected bird in a swarm + double x = 0.0; //best bird position + double xK = 0.0; //current best position of a randomly selected bird in a swarm + + for (int c = 0; c < coords; c++) + { + do K = u.RNDminusOne (popSize); + while (K == pos); + + x = agent [pos].cBest [c]; + xK = agent [K].cBest [c]; + + x = x + (xK - x) * FL * u.GaussDistribution (0, -1.0, 1.0, scroungerPower); + + a [pos].c [c] = u.SeInDiSp (x, rangeMin [c], rangeMax [c], rangeStep [c]); + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::BirdForaging (int pos) +{ + double x = 0.0; //current bird position + double p = 0.0; //best bird position + double g = 0.0; //best global position + double r1 = 0.0; //uniform random number [0.0 ... 1.0] + double r2 = 0.0; //uniform random number [0.0 ... 1.0] + + for (int c = 0; c < coords; c++) + { + x = a [pos].c [c]; + p = agent [pos].cBest [c]; + g = cB [c]; + + r1 = u.RNDprobab (); + r2 = u.RNDprobab (); + + x = x + (p - x) * C * r1 + (g - x) * S * r2; + + a [pos].c [c] = u.SeInDiSp (x, rangeMin [c], rangeMax [c], rangeStep [c]); + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::BirdVigilance (int pos) +{ + int K = 0; //position of a randomly selected bird in a swarm + double sumFit = 0.0; //best birds fitness sum + double pFitK = 0.0; //best fitness of a randomly selected bird + double pFit = 0.0; //best bird fitness + double A1 = 0.0; + double A2 = 0.0; + double r1 = 0.0; //uniform random number [ 0.0 ... 1.0] + double r2 = 0.0; //uniform random number [-1.0 ... 1.0] + double x = 0.0; //best bird position + double xK = 0.0; //best position of a randomly selected bird in a swarm + + ArrayInitialize (mean, 0.0); + + for (int i = 0; i < popSize; i++) sumFit += agent [i].fBest; + + for (int c = 0; c < coords; c++) + { + for (int i = 0; i < popSize; i++) mean [c] += a [i].c [c]; + + mean [c] /= popSize; + } + + do K = u.RNDminusOne (popSize); + while (K == pos); + + pFit = agent [pos].fBest; + pFitK = agent [K].fBest; + + A1 = a1 * exp (-pFit * N / (sumFit + e)); + A2 = a2 * exp (((pFit - pFitK) / (fabs (pFitK - pFit) + e)) * (N * pFitK / (sumFit + e))); + + for (int c = 0; c < coords; c++) + { + r1 = u.RNDprobab (); + r2 = u.RNDfromCI (-1, 1); + + x = agent [pos].cBest [c]; + xK = agent [K].cBest [c]; + + x = x + A1 * (mean [c] - x) * r1 + A2 * (xK - x) * r2; + + a [pos].c [c] = u.SeInDiSp (x, rangeMin [c], rangeMax [c], rangeStep [c]); + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSA::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]); +} +//—————————————————————————————————————————————————————————————————————————————— \ No newline at end of file diff --git a/MQL5/Include/Math/AOs/PopulationAO/AO_BSO_BrainStormOptimization.mqh b/MQL5/Include/Math/AOs/PopulationAO/AO_BSO_BrainStormOptimization.mqh new file mode 100644 index 0000000..3ec8c49 --- /dev/null +++ b/MQL5/Include/Math/AOs/PopulationAO/AO_BSO_BrainStormOptimization.mqh @@ -0,0 +1,557 @@ +//+————————————————————————————————————————————————————————————————————————————+ +//| C_AO_BSO | +//| Copyright 2007-2024, Andrey Dik | +//| https://www.mql5.com/ru/users/joo | +//—————————————————————————————————————————————————————————————————————————————+ + +//Article: https://www.mql5.com/ru/articles/14622 + +#include "#C_AO.mqh" + +//—————————————————————————————————————————————————————————————————————————————— +struct S_BSO_Agent +{ + double c []; //coordinates + double f; //fitness + int label; //cluster membership label + + void Init (int coords) + { + ArrayResize (c, coords); + f = -DBL_MAX; + label = -1; + } +}; +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +struct S_Clusters +{ + double centroid []; //cluster centroid + double f; //centroid fitness + int count; //number of points in the cluster + int ideasList []; //list of ideas + + void Init (int coords) + { + ArrayResize (centroid, coords); + f = -DBL_MAX; + ArrayResize (ideasList, 0, 100); + } +}; +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +class S_BSO_KMeans +{ + public: //-------------------------------------------------------------------- + + void KMeansInit (S_BSO_Agent &data [], int dataSizeClust, S_Clusters &clust []) + { + for (int i = 0; i < ArraySize (clust); i++) + { + int ind = MathRand () % dataSizeClust; + ArrayCopy (clust [i].centroid, data [ind].c, 0, 0, WHOLE_ARRAY); + } + } + + double VectorDistance (double &v1 [], double &v2 []) + { + double distance = 0.0; + for (int i = 0; i < ArraySize (v1); i++) + { + distance += (v1 [i] - v2 [i]) * (v1 [i] - v2 [i]); + } + return MathSqrt (distance); + } + + void KMeans (S_BSO_Agent &data [], int dataSizeClust, S_Clusters &clust []) + { + bool changed = true; + int nClusters = ArraySize (clust); + int cnt = 0; + + while (changed && cnt < 100) + { + cnt++; + changed = false; + + // Назначение точек данных к ближайшему центроиду + for (int d = 0; d < dataSizeClust; d++) + { + int closest_centroid = -1; + double closest_distance = DBL_MAX; + + if (data [d].f != -DBL_MAX) + { + for (int cl = 0; cl < nClusters; cl++) + { + double distance = VectorDistance (data [d].c, clust [cl].centroid); + + if (distance < closest_distance) + { + closest_distance = distance; + closest_centroid = cl; + } + } + + if (data [d].label != closest_centroid) + { + data [d].label = closest_centroid; + changed = true; + } + } + else + { + data [d].label = -1; + } + } + + + // Обновление центроидов + double sum_c []; + ArrayResize (sum_c, ArraySize (data [0].c)); + + for (int cl = 0; cl < nClusters; cl++) + { + ArrayInitialize (sum_c, 0.0); + + clust [cl].count = 0; + ArrayResize (clust [cl].ideasList, 0); + + for (int d = 0; d < dataSizeClust; d++) + { + if (data [d].label == cl) + { + for (int k = 0; k < ArraySize (data [d].c); k++) + { + sum_c [k] += data [d].c [k]; + } + + clust [cl].count++; + ArrayResize (clust [cl].ideasList, clust [cl].count); + clust [cl].ideasList [clust [cl].count - 1] = d; + } + } + + if (clust [cl].count > 0) + { + for (int k = 0; k < ArraySize (sum_c); k++) + { + clust [cl].centroid [k] = sum_c [k] / clust [cl].count; + } + } + } + } + } +}; +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +class C_AO_BSO : public C_AO +{ + public: //-------------------------------------------------------------------- + ~C_AO_BSO () { } + C_AO_BSO () + { + ao_name = "BSO"; + ao_desc = "Brain Storm Optimization"; + ao_link = "https://www.mql5.com/ru/articles/14622"; + + popSize = 25; //population size + + parentPopSize = 50; //parent population size; + clustersNumb = 5; //number of clusters + p_Replace = 0.1; //replace probability + p_One = 0.5; //probability of choosing one + p_One_center = 0.3; //probability of choosing one center + p_Two_center = 0.2; //probability of choosing two centers + k_Mutation = 20.0; //mutation coefficient + distribCoeff = 1.0; //distribution coefficient + + ArrayResize (params, 9); + + params [0].name = "popSize"; params [0].val = popSize; + + params [1].name = "parentPopSize"; params [1].val = parentPopSize; + params [2].name = "clustersNumb"; params [2].val = clustersNumb; + params [3].name = "p_Replace"; params [3].val = p_Replace; + params [4].name = "p_One"; params [4].val = p_One; + params [5].name = "p_One_center"; params [5].val = p_One_center; + params [6].name = "p_Two_center"; params [6].val = p_Two_center; + params [7].name = "k_Mutation"; params [7].val = k_Mutation; + params [8].name = "distribCoeff"; params [8].val = distribCoeff; + } + + void SetParams () + { + popSize = (int)params [0].val; + + parentPopSize = (int)params [1].val; + clustersNumb = (int)params [2].val; + p_Replace = params [3].val; + p_One = params [4].val; + p_One_center = params [5].val; + p_Two_center = params [6].val; + k_Mutation = params [7].val; + distribCoeff = params [8].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 parentPopSize; //parent population size; + int clustersNumb; //number of clusters + double p_Replace; //replace probability + double p_One; //probability of choosing one + double p_One_center; //probability of choosing one center + double p_Two_center; //probability of choosing two centers + double k_Mutation; //mutation coefficient + double distribCoeff; //distribution coefficient + + S_BSO_Agent agent []; + S_BSO_Agent parents []; + + S_Clusters clusters []; + S_BSO_KMeans km; + + private: //------------------------------------------------------------------- + S_BSO_Agent parentsTemp []; + int epochs; + int epochsNow; +}; +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +bool C_AO_BSO::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; + + //---------------------------------------------------------------------------- + ArrayResize (agent, popSize); + for (int i = 0; i < popSize; i++) agent [i].Init (coords); + + ArrayResize (clusters, clustersNumb); + for (int i = 0; i < clustersNumb; i++) clusters [i].Init (coords); + + ArrayResize (parents, parentPopSize + popSize); + ArrayResize (parentsTemp, parentPopSize + popSize); + + for (int i = 0; i < parentPopSize + popSize; i++) + { + parents [i].Init (coords); + parentsTemp [i].Init (coords); + } + + epochs = epochsP; + epochsNow = 0; + + return true; +} +//—————————————————————————————————————————————————————————————————————————————— + +/* +1. Инициализация популяции из n индивидов, m кластеров и максимального числа итераций gmax. +2. Оценка приспособленности + +Цикл итераций до достижения максимального числа итераций gmax. + Кластеризация: Индивиды группируются в m кластеров в зависимости от их приспособленности. + Установить лучшее решение в кластере как центр кластера. + + Если Preplace + генерируется новый индивид, который заменяет выбранный центр кластера (Из центра кластера) + + Если Pone + выбирается индивид из одного кластера. + + Если Pone_center + выбирается центр кластера для мутации, + иначе + случайный индивид из этого кластера. + Иначе + выбираются индивиды из двух кластеров. + + Если Ptwo_center, + то два центра кластера объединяются и мутируют + иначе + случайно выбираются два индивида из каждого выбранного кластера, которые затем объединяются и мутируют. + + Мутация: + Полученный индивид подвергается мутации с помощью гауссовой мутации + + Вычисляется его приспособленность. + + Отбор: + отбор, в результате которого в популяции остаются только наилучшие индивиды. +*/ + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSO::Moving () +{ + epochsNow++; + + //---------------------------------------------------------------------------- + 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]); + + agent [i].c [c] = a [i].c [c]; + } + } + + return; + } + + //---------------------------------------------------------------------------- + //---------------------------------------------------------------------------- + int cIndx_1 = 0; //индекс в списке непустых кластеров + int iIndx_1 = 0; //индекс в списке идей в кластере + int cIndx_2 = 0; //индекс в списке непустых кластеров + int iIndx_2 = 0; //индекс в списке идей в кластере + double min = 0.0; + double max = 0.0; + double dist = 0.0; + double val = 0.0; + double X1 = 0.0; + double X2 = 0.0; + int clListSize = 0; + int clustList []; + ArrayResize (clustList, 0, clustersNumb); + + //---------------------------------------------------------------------------- + //составим список непустых кластеров + for (int cl = 0; cl < clustersNumb; cl++) + { + if (clusters [cl].count > 0) + { + clListSize++; + ArrayResize (clustList, clListSize); + clustList [clListSize - 1] = cl; + } + } + + for (int i = 0; i < popSize; i++) + { + //========================================================================== + //генерация новой идеи, которая заменяет выбранный центр кластера (смещение центра кластера) + if (u.RNDprobab () < p_Replace) + { + cIndx_1 = u.RNDminusOne (clListSize); + + for (int c = 0; c < coords; c++) + { + val = clusters [clustList [cIndx_1]].centroid [c]; + + dist = (rangeMax [c] - rangeMin [c]) * 0.8; + + min = val - dist; if (min < rangeMin [c]) min = rangeMin [c]; + max = val + dist; if (max > rangeMax [c]) max = rangeMax [c]; + + val = u.GaussDistribution (val, min, max, 3); + val = u.SeInDiSp (val, rangeMin [c], rangeMax [c], rangeStep [c]); + + clusters [clustList [cIndx_1]].centroid [c] = val; + } + } + + //========================================================================== + //выбирается идея из одного кластера + if (u.RNDprobab () < p_One) + { + cIndx_1 = u.RNDminusOne (clListSize); + + //------------------------------------------------------------------------ + if (u.RNDprobab () < p_One_center) //выбирается центр кластера + { + for (int c = 0; c < coords; c++) + { + a [i].c [c] = clusters [clustList [cIndx_1]].centroid [c]; + } + } + //------------------------------------------------------------------------ + else //случайная идея из этого кластера + { + iIndx_1 = u.RNDminusOne (clusters [clustList [cIndx_1]].count); + + for (int c = 0; c < coords; c++) + { + a [i].c [c] = parents [clusters [clustList [cIndx_1]].ideasList [iIndx_1]].c [c]; + } + } + } + //========================================================================== + //выбираются идеи из двух кластеров + else + { + if (clListSize == 1) + { + cIndx_1 = 0; + cIndx_2 = 0; + } + else + { + if (clListSize == 2) + { + cIndx_1 = 0; + cIndx_2 = 1; + } + else + { + cIndx_1 = u.RNDminusOne (clListSize); + + do + { + cIndx_2 = u.RNDminusOne (clListSize); + } + while (cIndx_1 == cIndx_2); + } + } + + //------------------------------------------------------------------------ + if (u.RNDprobab () < p_Two_center) //выбрали два центра кластеров + { + for (int c = 0; c < coords; c++) + { + X1 = clusters [clustList [cIndx_1]].centroid [c]; + X2 = clusters [clustList [cIndx_2]].centroid [c]; + + a [i].c [c] = u.RNDfromCI (X1, X2); + } + } + //------------------------------------------------------------------------ + else //две идеи из двух выбранных кластеров + { + iIndx_1 = u.RNDminusOne (clusters [clustList [cIndx_1]].count); + iIndx_2 = u.RNDminusOne (clusters [clustList [cIndx_2]].count); + + for (int c = 0; c < coords; c++) + { + X1 = parents [clusters [clustList [cIndx_1]].ideasList [iIndx_1]].c [c]; + X2 = parents [clusters [clustList [cIndx_2]].ideasList [iIndx_2]].c [c]; + + a [i].c [c] = u.RNDfromCI (X1, X2); + } + } + } + + //========================================================================== + //Мутация + for (int c = 0; c < coords; c++) + { + int x = (int)u.Scale (epochsNow, 1, epochs, 1, 200); + + double ξ = (1.0 / (1.0 + exp (-((100 - x) / k_Mutation))));// * u.RNDprobab (); + + double dist = (rangeMax [c] - rangeMin [c]) * distribCoeff * ξ; + double min = a [i].c [c] - dist; if (min < rangeMin [c]) min = rangeMin [c]; + double max = a [i].c [c] + dist; if (max > rangeMax [c]) max = rangeMax [c]; + + val = a [i].c [c]; + + a [i].c [c] = u.GaussDistribution (val, min, max, 8); + } + + //Сохраним агента----------------------------------------------------------- + for (int c = 0; c < coords; c++) + { + val = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); + + a [i].c [c] = val; + agent [i].c [c] = val; + } + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSO::Revision () +{ + //получить приспособленность-------------------------------------------------- + for (int i = 0; i < popSize; i++) + { + agent [i].f = a [i].f; + } + + //перенести новые идеи в популяцию-------------------------------------------- + for (int i = parentPopSize; i < parentPopSize + popSize; i++) + { + parents [i] = agent [i - parentPopSize]; + } + + //отсортировать родительскую популяцию---------------------------------------- + u.Sorting (parents, parentsTemp, parentPopSize + popSize); + + if (parents [0].f > fB) + { + fB = parents [0].f; + ArrayCopy (cB, parents [0].c, 0, 0, WHOLE_ARRAY); + } + + + //выполнить кластеризацию----------------------------------------------------- + if (!revision) + { + km.KMeansInit (parents, parentPopSize, clusters); + revision = true; + } + + km.KMeansInit (parents, parentPopSize, clusters); + km.KMeans (parents, parentPopSize, clusters); + + //Назначить лучшее решение кластера центром кластера-------------------------- + for (int cl = 0; cl < clustersNumb; cl++) + { + clusters [cl].f = -DBL_MAX; + + if (clusters [cl].count > 0) + { + for (int p = 0; p < parentPopSize; p++) + { + if (parents [p].label == cl) + { + if (parents [p].f > clusters [cl].f) + { + clusters [cl].f = parents [p].f; + ArrayCopy (clusters [cl].centroid, parents [p].c, 0, 0, WHOLE_ARRAY); + } + } + } + } + } +} +//—————————————————————————————————————————————————————————————————————————————— + +//—————————————————————————————————————————————————————————————————————————————— +void C_AO_BSO::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]); +} +//—————————————————————————————————————————————————————————————————————————————— diff --git a/MQL5/Include/Math/AOs/PopulationAO/AO_Boids_BoidsAlgorithm.mqh b/MQL5/Include/Math/AOs/PopulationAO/AO_Boids_BoidsAlgorithm.mqh new file mode 100644 index 0000000000000000000000000000000000000000..587edaca07a0900485a75294ee427a031f687e66 GIT binary patch literal 28034 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
G+}@&9lMr9`aB;p9j2T!Gdbn?8CC5AE`##b zv|@`={-$`C<*We_FNah|I((VSJzraNtxrNx?nv8VV{{l)WW=LfdqiGi|vC$U7M~!#yh6p=Ysly6L4I zEYsf6qWK;62PyAE8~k_g%6tp&M=r{{)s^nW!PC~%<#w3kDNQ{avLz>PiEBA!+gWr` zjWP-?3$W38jtWjZQn-~WPag|(?9#9!0e<6jE5pLbHHnWz$RE-(5d1$Zc$2BnhkcZ@ zr|IhT?Dfm;ukydfeBS*<&LFSJQ%n!!^`AnQN1K-uTh ztmg^tiwCD(MH);fi?b`-;b}bI!Dd zrL<4FsykA-a%u$}dFF}jYE@ys+oIHb-D|^Yd$|;_-)RpNwf1osT}Ev`lk?GEW4tIn wys9ZN_VIBR$?56(@)^PviA1)h_``AXEl2iq5Jx_gXvOK2K0Q%>FHg4df4W$tkN^Mx literal 0 HcmV?d00001 diff --git a/MQL5/Include/Math/AOs/TestFunctions.mqh b/MQL5/Include/Math/AOs/TestFunctions.mqh new file mode 100644 index 0000000000000000000000000000000000000000..399655e0d988db4698ca0f1c9ac6932921148276 GIT binary patch literal 41686 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 HM40~rouvB9 literal 0 HcmV?d00001 diff --git a/MQL5/Include/Math/AOs/TestStandFunctions.mqh b/MQL5/Include/Math/AOs/TestStandFunctions.mqh new file mode 100644 index 0000000000000000000000000000000000000000..2e303576e17ea84d1634b8fcba7532181b78c34d GIT binary patch literal 17460 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 D<=2#~ literal 0 HcmV?d00001 diff --git a/MQL5/Include/Math/AOs/Textures/checker.bmp b/MQL5/Include/Math/AOs/Textures/checker.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0d65c538b8a39a3d5491f1c40a5a63e7eeb26943 GIT binary patch literal 196662 zcmeIy!3l&g00q&=Hem@{fd%Z{=F^aCND=Qc0Y&jJF!S+uU*j{@x!&u$9*%t-<6Lj= z+28l`zCRsmV0Neh8bA0$;|HHj&>Coh)_|=a-PVuZ0Cog)_|=a-PVuZ0Cog)_|=a-PVuZ0Cog)_|=a-PVuZ0Cog)_|=a-PVuZ0Cog)_|=a-PVuZ0Cog z)_|=a-PVuZ0Cog)_|=a z-PVuZ0qocsqqjh7paoh3wtjS5KY9za z23nvsVCzS>^`o~yYoG;M1Gav2TR(aWv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAW zpfzCYN4NE(w?J#41zH2Peso(udJD7$TA(#x>qocsqqjh7paoh3wtjS5KY9za23nvs zVCzS>^`o~yYoG;M1Gav2TR(aWv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAWpfzCY zN4NE(w?J#41zH2Peso(udJD7$TA(#x>qocsqqjh7paoh3wtjS5KY9za23nvsVCzS> z^`o~yYoG;M1Gav2TR(aWv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAWpfzCYN4NE( zw?J#41zH2Peso(udJD7$TA(#x>qocsqqjh7paoh3wtjS5KY9za23nvsVCzS>^`o~y zYoG;M1Gav2TR(aWv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAWpfzCYN4NE(w?J#4 z1zH2Peso(udJD7$TA(#x>qocsqqjh7paoh3wtjS5KY9za23nvsVCzS>^`o~yYoG;M z1Gav2TR(aWv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAWpfzCYN4NE(w?J#41zH2P zeso(udJD7$TA(#x>qocsqqjh7paoh3wtjS5KY9za23nvsVCzS>^`o~yYoG;M1Gav2 zTR(aWv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAWpfzCYN4NE(w?J#41zH2Peso(u zdJD7$TA(#x>qocsqqjh7paoh3wtjS5KY9za23nvsVCzS>^`o~yYoG;M1Gav2TR(aW zv<6zBHDK#UxAmj9Kx?1{S_8IzbXz}q3$zAWpfzCYN4NE(w?J#41zH2Peso(udJD7$ zTA(#x>qocsqqjh7paoh3wtjS5KY9za23nvsVCzS>^`o~yYoG;M1Gav2TR-|Ap@6C! literal 0 HcmV?d00001 diff --git a/MQL5/Include/Math/AOs/Utilities.mqh b/MQL5/Include/Math/AOs/Utilities.mqh new file mode 100644 index 0000000000000000000000000000000000000000..d7f7a21cd304dd01beff961f8331aef130736066 GIT binary patch literal 18320 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