Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 91e79ee3b0 | |||
| dea4bde628 | |||
| 05e4ca47cf | |||
| b2d0c0066b | |||
| 1ffbc1bc5c | |||
| b5dbcdc3e3 | |||
| e70141e538 | |||
| 4844f86fe5 | |||
| e6e124eb58 | |||
| 5c1b23c032 | |||
| b7c018d497 | |||
| 2e574ae823 | |||
| 0a63ecccb2 | |||
| 4bd5f8834d | |||
| c6034827bc | |||
| f637806bca | |||
| ba40abf6f6 | |||
| e53bab4909 | |||
| 0825823440 | |||
| 7fa2ca611e | |||
| 922df141b2 | |||
| 90ee403894 | |||
| 6e8f7cd067 | |||
| a05a7e3dcf | |||
| 507ddd2f23 | |||
| 15416907a7 | |||
| 2553083f7d | |||
| ac0c2b08a9 | |||
| cb0b1b2008 | |||
| 675d77f2f8 | |||
| 99d71dc20e | |||
| 314cc297d9 | |||
| f6c93b57a9 | |||
| 16b268c491 | |||
| 2c1f8f17a5 | |||
| 58112a873c | |||
| e4e7c9a543 | |||
| be46ca30fe | |||
| 18cf0bee37 | |||
| 07f390bde3 | |||
| a90f02f75d | |||
| 16035c7574 | |||
| 0e429f9529 | |||
| 7e6e67e437 | |||
| e7d90a6a6b | |||
| 9d2c70a8be | |||
| 59868b143c | |||
| ddaef2d134 | |||
| 88a04e506a | |||
| aa09771f0c | |||
| df1c7a0a9e | |||
| 4b655f2e06 | |||
| d8ad32a373 | |||
| 0da15ec4f5 | |||
| 081de740e2 | |||
| 49dab80b7f | |||
| 832d9d89d4 | |||
| d41114d269 | |||
| a3956f73d5 | |||
| 53894e430f | |||
| 5f0e68b48d | |||
| 8b1aa2561e | |||
| 39f3379a4b | |||
| 9c9e972c1a | |||
| 75a50160cb | |||
| 29dfaf3a00 | |||
| 382b4bc431 | |||
| df45edcddc | |||
| 606057e752 | |||
| e88dd381bb | |||
| 11f6b84458 | |||
| 090daaad2a | |||
| 4c0a57b079 | |||
| c192c7bcf4 | |||
| f9f2726bc4 | |||
| 03f12ea18b | |||
| a63b5e214a | |||
| 11dfcb0ebf | |||
| 73def52d32 | |||
| f8efe21cb4 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,308 @@
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
//| C_AO_BChimp |
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//———————————————————————————————————————————————————————————————————+
|
||||
|
||||
#include "#C_AO.mqh"
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Chimp Optimization Algorithm — континуальное ядро (BChimp). |
|
||||
//| |
|
||||
//| Источник: Ayeche, Alti — Enhanced Binary Chimp Optimization |
|
||||
//| (Hum-Cent Intell Syst, 2023), поверх базового ChOA (Khishe, |
|
||||
//| Mosavi, 2020). Исходник — бинарный feature-selection (BChimp1/ |
|
||||
//| BChimp2). Для C_AO бинаризация снята: остаётся континуальное |
|
||||
//| ядро ChOA, позиция = среднее четырёх кандидатов от вожаков |
|
||||
//| (ядро BChimp2 до сигмоид-трансфера). |
|
||||
//| |
|
||||
//| Содержательная механика (сохранена полностью): |
|
||||
//| - четвёрка вожаков: attacker / barrier / chaser / driver — |
|
||||
//| четыре ЛУЧШИХ позиции (элитарно, best-ever); |
|
||||
//| - четыре группы с РАЗНЫМИ законами динамических коэффициентов |
|
||||
//| (корневой ^1/3 и кубический ^3), что разводит баланс |
|
||||
//| exploration/exploitation по вожакам; |
|
||||
//| - хаотический множитель m[i] по Piecewise-карте, статический |
|
||||
//| на агента (как в источнике — генерируется один раз). |
|
||||
//| |
|
||||
//| Расчёт на агента/координату для каждого вожака k=0..3: |
|
||||
//| A_k = a·C1G_k·(2·rand − 1) — СИММЕТРИЧЕН (E=0) |
|
||||
//| C_k = C2G_k·rand |
|
||||
//| D_k = | C_k·Lead_k − m_i·x_i | |
|
||||
//| X_k = Lead_k − A_k·D_k |
|
||||
//| x_new = (X_0 + X_1 + X_2 + X_3) / 4 |
|
||||
//| где a = 2 − 2·(t/T) (спад 2→0), амплитуда a·C1G_k → 0. |
|
||||
//| |
|
||||
//| Важно: в исходнике A = a·(2·C1G·rand − 1) c E[A]=a·(C1G−1)≠0 — |
|
||||
//| смещение сносит континуальную популяцию в угол rangeMin (в |
|
||||
//| бинарном домене скрыто сигмоид-трансфером). Здесь A приведён |
|
||||
//| к симметричной канонической форме ChOA: A = f·(2r−1), f=a·C1G. |
|
||||
//| |
|
||||
//| Версия ЭТАЛОННАЯ: greedy-приёмки/откатов нет (в источнике их |
|
||||
//| нет), популяция движется свободно, элитарны только вожаки. |
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| вожак стаи: координаты + фитнес |
|
||||
//+------------------------------------------------------------------+
|
||||
struct S_Leader
|
||||
{
|
||||
double c []; // координаты
|
||||
double f; // фитнес
|
||||
|
||||
void Init(const int coords)
|
||||
{
|
||||
ArrayResize(c, coords);
|
||||
f = -DBL_MAX;
|
||||
}
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| персональное состояние шимпанзе |
|
||||
//+------------------------------------------------------------------+
|
||||
struct S_Chimp
|
||||
{
|
||||
double m; // хаотический множитель (Piecewise-карта), статичен
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
class C_AO_BChimp : public C_AO
|
||||
{
|
||||
public:
|
||||
~C_AO_BChimp() {}
|
||||
C_AO_BChimp()
|
||||
{
|
||||
ao_name = "BChimp";
|
||||
ao_desc = "Chimp Optimization Algorithm";
|
||||
ao_link = "https://www.mql5.com/ru/articles/23132";
|
||||
|
||||
popSize = 30;
|
||||
|
||||
ArrayResize(params, 1);
|
||||
params [0].name = "popSize";
|
||||
params [0].val = popSize;
|
||||
}
|
||||
|
||||
void SetParams()
|
||||
{
|
||||
popSize = (int)params [0].val;
|
||||
}
|
||||
|
||||
bool Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0);
|
||||
|
||||
void Moving();
|
||||
void Revision();
|
||||
|
||||
private:
|
||||
//--- четыре вожака: 0=attacker, 1=barrier, 2=chaser, 3=driver
|
||||
S_Leader lead [4];
|
||||
|
||||
//--- персональное состояние агентов
|
||||
S_Chimp chimp [];
|
||||
|
||||
//--- счётчики итераций (для отношения t/T)
|
||||
int epochs;
|
||||
int epochsDen;
|
||||
int epochNow;
|
||||
|
||||
//--- попытка вставить агента в элитарную лесенку вожаков
|
||||
void InsertLeader(const int i);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool C_AO_BChimp::Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0)
|
||||
{
|
||||
if(!StandardInit(rangeMinP, rangeMaxP, rangeStepP))
|
||||
return false;
|
||||
|
||||
//--- начальная случайная популяция в cP[] (попадёт в c[] на первом Moving)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].cP [c] = u.RNDfromCI(rangeMin [c], rangeMax [c]);
|
||||
|
||||
//--- вожаки
|
||||
for(int k = 0; k < 4; k++)
|
||||
lead [k].Init(coords);
|
||||
|
||||
//--- персональное состояние
|
||||
ArrayResize(chimp, popSize);
|
||||
|
||||
//--- хаотический множитель m[i] — Piecewise-карта (index=6 в источнике),
|
||||
// P=0.4, x0=0.7, Value=1; значение берётся ДО обновления
|
||||
double P = 0.4;
|
||||
double x = 0.7;
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
chimp [i].m = x;
|
||||
if(x >= 0.0 && x < P)
|
||||
x = x / P;
|
||||
else
|
||||
if(x >= P && x < 0.5)
|
||||
x = (x - P) / (0.5 - P);
|
||||
else
|
||||
if(x >= 0.5 && x < 1.0 - P)
|
||||
x = (1.0 - P - x) / (0.5 - P);
|
||||
else
|
||||
x = (1.0 - x) / P;
|
||||
}
|
||||
|
||||
//--- счётчики итераций
|
||||
epochs = epochsP;
|
||||
epochsDen = (epochs > 1) ? epochs - 1 : 1;
|
||||
epochNow = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving |
|
||||
//| |
|
||||
//| 1. первый прогон: cP -> c (внешний цикл оценит FF); |
|
||||
//| 2. далее: a и четыре группы коэффициентов на итерацию; |
|
||||
//| 3. для каждого агента/координаты — четыре кандидата от вожаков, |
|
||||
//| усреднение, проекция в границы (SeInDiSp). |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BChimp::Moving()
|
||||
{
|
||||
//--- первый прогон: cP -> c
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = u.SeInDiSp(a [i].cP [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
return;
|
||||
}
|
||||
|
||||
//--- отношение t/T (зажато в 1.0); a: спад 2 -> 0
|
||||
epochNow++;
|
||||
double tRatio = (double)epochNow / (double)epochsDen;
|
||||
if(tRatio > 1.0)
|
||||
tRatio = 1.0;
|
||||
|
||||
double aCoef = 2.0 - 2.0 * tRatio;
|
||||
|
||||
//--- групповые динамические коэффициенты
|
||||
// u1 = (t/T)^(1/3) — корневой закон, u3 = (t/T)^3 — кубический
|
||||
double u1 = MathPow(tRatio, 1.0 / 3.0);
|
||||
double u3 = tRatio * tRatio * tRatio;
|
||||
|
||||
double C1G [4], C2G [4];
|
||||
C1G [0] = 1.95 - 2.0 * u1;
|
||||
C2G [0] = 2.0 * u1 + 0.5; // группа 1 (attacker)
|
||||
C1G [1] = 1.95 - 2.0 * u1;
|
||||
C2G [1] = 2.0 * u3 + 0.5; // группа 2 (barrier)
|
||||
C1G [2] = -2.0 * u3 + 2.5;
|
||||
C2G [2] = 2.0 * u1 + 0.5; // группа 3 (chaser)
|
||||
C1G [3] = -2.0 * u3 + 2.5;
|
||||
C2G [3] = 2.0 * u3 + 0.5; // группа 4 (driver)
|
||||
|
||||
//--- движение
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
double mi = chimp [i].m;
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double xi = a [i].c [c];
|
||||
double sum = 0.0;
|
||||
|
||||
for(int k = 0; k < 4; k++)
|
||||
{
|
||||
//--- A симметричен относительно 0: амплитуда aCoef*C1G[k] -> 0
|
||||
// к концу прогона (E[A]=0, нет сноса в угол). C масштабирован
|
||||
// к канону [0..~2.5]. Знак C1G[k] роли не играет — множится
|
||||
// на симметричное (2r-1).
|
||||
double Ak = aCoef * C1G [k] * (2.0 * u.RNDprobab() - 1.0);
|
||||
double Ck = C2G [k] * u.RNDprobab();
|
||||
double Dk = MathAbs(Ck * lead [k].c [c] - mi * xi);
|
||||
sum += lead [k].c [c] - Ak * Dk;
|
||||
}
|
||||
|
||||
double v = sum / 4.0;
|
||||
a [i].c [c] = u.SeInDiSp (v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Revision |
|
||||
//| |
|
||||
//| Обновление личных/глобального лучших + элитарная актуализация |
|
||||
//| четвёрки вожаков (best-ever). Откатов нет — версия эталонная. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BChimp::Revision()
|
||||
{
|
||||
//--- обновление личных и глобального лучших
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(a [i].f > a [i].fB)
|
||||
{
|
||||
a [i].fB = a [i].f;
|
||||
ArrayCopy(a [i].cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
if(a [i].f > fB)
|
||||
{
|
||||
fB = a [i].f;
|
||||
ArrayCopy(cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
}
|
||||
|
||||
//--- элитарная актуализация вожаков (инициализация на первом вызове
|
||||
// и поддержание top-4 на последующих)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
InsertLeader(i);
|
||||
|
||||
if(!revision)
|
||||
revision = true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| InsertLeader — вставка агента в лесенку вожаков |
|
||||
//| Вожаки отсортированы по убыванию фитнеса (lead[0] — лучший). |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BChimp::InsertLeader(const int i)
|
||||
{
|
||||
double f = a [i].f;
|
||||
|
||||
int p = -1;
|
||||
if(f > lead [0].f)
|
||||
p = 0;
|
||||
else
|
||||
if(f > lead [1].f)
|
||||
p = 1;
|
||||
else
|
||||
if(f > lead [2].f)
|
||||
p = 2;
|
||||
else
|
||||
if(f > lead [3].f)
|
||||
p = 3;
|
||||
|
||||
if(p < 0)
|
||||
return;
|
||||
|
||||
//--- сдвиг вниз от хвоста к позиции вставки
|
||||
for(int s = 3; s > p; s--)
|
||||
{
|
||||
lead [s].f = lead [s - 1].f;
|
||||
ArrayCopy(lead [s].c, lead [s - 1].c, 0, 0, coords);
|
||||
}
|
||||
|
||||
//--- вставка
|
||||
lead [p].f = f;
|
||||
ArrayCopy(lead [p].c, a [i].c, 0, 0, coords);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,401 @@
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
//| C_AO_BEA |
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//———————————————————————————————————————————————————————————————————+
|
||||
|
||||
#include "#C_AO.mqh"
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
struct S_BEA_Ind
|
||||
{
|
||||
double c []; // координаты (валидные, уже прогнаны через SeInDiSp)
|
||||
double f; // фитнес
|
||||
|
||||
void Init(int coords)
|
||||
{
|
||||
ArrayResize(c, coords);
|
||||
f = -DBL_MAX;
|
||||
}
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
class C_AO_BEA : public C_AO
|
||||
{
|
||||
public:
|
||||
~C_AO_BEA() {}
|
||||
C_AO_BEA()
|
||||
{
|
||||
ao_name = "BEA";
|
||||
ao_desc = "Bacterial Evolutionary Algorithm";
|
||||
ao_link = "https://www.mql5.com/ru/articles/23232";
|
||||
|
||||
popSize = 10; // число бактерий
|
||||
Nc = 2; // свежих мутантов сегмента на бактерию (>=1)
|
||||
Nseg = 10; // число сегментов хромосомы
|
||||
nTrans = 2; // эпох переноса генов на поколение
|
||||
transFrac = 0.2; // длина переносимого блока как доля coords (0..1]
|
||||
|
||||
ArrayResize(params, 5);
|
||||
params [0].name = "popSize"; params [0].val = popSize;
|
||||
params [1].name = "Nc"; params [1].val = Nc;
|
||||
params [2].name = "Nseg"; params [2].val = Nseg;
|
||||
params [3].name = "nTrans"; params [3].val = nTrans;
|
||||
params [4].name = "transFrac"; params [4].val = transFrac;
|
||||
}
|
||||
|
||||
void SetParams()
|
||||
{
|
||||
popSize = (int)params [0].val;
|
||||
Nc = (int)params [1].val;
|
||||
Nseg = (int)params [2].val;
|
||||
nTrans = (int)params [3].val;
|
||||
transFrac = params [4].val;
|
||||
|
||||
//--- предохранители
|
||||
if(popSize < 1)
|
||||
popSize = 1;
|
||||
if(Nc < 1)
|
||||
Nc = 1; // число свежих мутантов на сегмент
|
||||
if(Nseg < 1)
|
||||
Nseg = 1;
|
||||
if(nTrans < 0)
|
||||
nTrans = 0;
|
||||
if(transFrac <= 0.0)
|
||||
transFrac = 0.01;
|
||||
if(transFrac > 1.0)
|
||||
transFrac = 1.0;
|
||||
}
|
||||
|
||||
bool Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0);
|
||||
|
||||
void Moving();
|
||||
void Revision();
|
||||
|
||||
//--- видимые параметры
|
||||
int Nc; // клонов
|
||||
int Nseg; // сегментов
|
||||
int nTrans; // эпох переноса генов
|
||||
double transFrac; // доля coords для блока переноса
|
||||
|
||||
private:
|
||||
//--- фазы конечного автомата
|
||||
enum E_Phase { PH_MUT = 0, PH_TRANS = 1 };
|
||||
E_Phase phase;
|
||||
int segIdx; // текущий сегмент в мутации
|
||||
int cloneIdx; // текущий клон (срез оценки) в мутации
|
||||
int transIdx; // текущая эпоха переноса
|
||||
|
||||
//--- данные (массивы структур)
|
||||
S_BEA_Ind bact []; // [popSize] — закреплённые бактерии
|
||||
S_BEA_Ind clone []; // [popSize * Nc] — рабочие клоны
|
||||
int ord []; // [popSize] — индексы для сортировки
|
||||
|
||||
int transLen; // длина блока переноса (из transFrac)
|
||||
|
||||
//--- вспомогательные
|
||||
void SegBounds(int s, int &lo, int &hi);
|
||||
void BuildClonesForSeg(int s);
|
||||
void DoGeneTransfer();
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool C_AO_BEA::Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0)
|
||||
{
|
||||
if(!StandardInit(rangeMinP, rangeMaxP, rangeStepP))
|
||||
return false;
|
||||
|
||||
//--- сегментов не больше, чем координат
|
||||
if(Nseg > coords)
|
||||
Nseg = coords;
|
||||
|
||||
//--- длина блока переноса
|
||||
transLen = (int)MathRound(transFrac * coords);
|
||||
if(transLen < 1)
|
||||
transLen = 1;
|
||||
if(transLen > coords)
|
||||
transLen = coords;
|
||||
|
||||
//--- буферы (массивы структур)
|
||||
ArrayResize(bact, popSize);
|
||||
ArrayResize(clone, popSize * Nc);
|
||||
ArrayResize(ord, popSize);
|
||||
|
||||
for(int i = 0; i < popSize; i++)
|
||||
bact [i].Init(coords);
|
||||
for(int i = 0; i < popSize * Nc; i++)
|
||||
clone [i].Init(coords);
|
||||
|
||||
//--- стартовая случайная популяция бактерий
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
bact [i].c [c] = u.SeInDiSp(u.RNDfromCI(rangeMin [c], rangeMax [c]),
|
||||
rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
bact [i].f = -DBL_MAX;
|
||||
}
|
||||
|
||||
//--- стартовое состояние автомата
|
||||
phase = PH_MUT;
|
||||
segIdx = 0;
|
||||
cloneIdx = 0;
|
||||
transIdx = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| SegBounds — границы сегмента s в [lo, hi) с равномерным |
|
||||
//| распределением остатка координат по сегментам |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BEA::SegBounds(int s, int &lo, int &hi)
|
||||
{
|
||||
lo = (int)((long)s * coords / Nseg);
|
||||
hi = (int)((long)(s + 1) * coords / Nseg);
|
||||
if(lo < 0)
|
||||
lo = 0;
|
||||
if(hi > coords)
|
||||
hi = coords;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| BuildClonesForSeg — снять с каждой бактерии Nc клонов и во |
|
||||
//| ВСЕХ клонах случайно регенерировать координаты сегмента s. |
|
||||
//| Инкумбент не хранится отдельным клоном: его фитнес помнится в |
|
||||
//| bact.f и сравнивается при закреплении (см. Revision). |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BEA::BuildClonesForSeg(int s)
|
||||
{
|
||||
int lo, hi;
|
||||
SegBounds(s, lo, hi);
|
||||
|
||||
for(int b = 0; b < popSize; b++)
|
||||
{
|
||||
for(int j = 0; j < Nc; j++)
|
||||
{
|
||||
int idx = b * Nc + j;
|
||||
|
||||
//--- копия бактерии вне сегмента
|
||||
for(int c = 0; c < coords; c++)
|
||||
clone [idx].c [c] = bact [b].c [c];
|
||||
|
||||
//--- регенерация сегмента во ВСЕХ клонах. Инкумбент хранится
|
||||
// отдельно (bact.f) и сравнивается на этапе закрепления —
|
||||
// переоценивать его клоном не нужно, экономим вызовы FF.
|
||||
for(int c = lo; c < hi; c++)
|
||||
clone [idx].c [c] = u.SeInDiSp(u.RNDfromCI(rangeMin [c], rangeMax [c]),
|
||||
rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
|
||||
clone [idx].f = -DBL_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| DoGeneTransfer — сортировка популяции и инфицирование «слабой» |
|
||||
//| половины блоками из «сильной». Модифицирует bact[] на месте. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BEA::DoGeneTransfer()
|
||||
{
|
||||
if(popSize < 2)
|
||||
return;
|
||||
|
||||
//--- сортировка индексов по фитнесу бактерий (по убыванию)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
ord [i] = i;
|
||||
|
||||
for(int i = 0; i < popSize - 1; i++)
|
||||
{
|
||||
int bi = i;
|
||||
for(int j = i + 1; j < popSize; j++)
|
||||
if(bact [ord [j]].f > bact [ord [bi]].f)
|
||||
bi = j;
|
||||
int t = ord [i];
|
||||
ord [i] = ord [bi];
|
||||
ord [bi] = t;
|
||||
}
|
||||
|
||||
int half = popSize / 2;
|
||||
if(half < 1)
|
||||
half = 1;
|
||||
|
||||
int span = coords - transLen + 1;
|
||||
if(span < 1)
|
||||
span = 1;
|
||||
|
||||
//--- каждый приёмник «слабой» половины принимает блок от случайного
|
||||
// источника «сильной» половины
|
||||
for(int k = half; k < popSize; k++)
|
||||
{
|
||||
int dst = ord [k];
|
||||
int src = ord [u.RNDminusOne(half)];
|
||||
int start = u.RNDminusOne(span);
|
||||
|
||||
for(int t = 0; t < transLen; t++)
|
||||
{
|
||||
int c = start + t;
|
||||
if(c < coords)
|
||||
bact [dst].c [c] = bact [src].c [c];
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving |
|
||||
//| Заполняет слоты a[i].c кандидатами для оценки этой эпохи. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BEA::Moving()
|
||||
{
|
||||
//--- первый прогон: бактерии -> слоты для первичной оценки FF
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = u.SeInDiSp(bact [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(phase == PH_MUT)
|
||||
{
|
||||
//--- на старте сегмента строим клоны
|
||||
if(cloneIdx == 0)
|
||||
BuildClonesForSeg(segIdx);
|
||||
|
||||
//--- грузим текущий клон каждой бактерии в слоты
|
||||
for(int b = 0; b < popSize; b++)
|
||||
{
|
||||
int idx = b * Nc + cloneIdx;
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [b].c [c] = clone [idx].c [c];
|
||||
}
|
||||
}
|
||||
else // PH_TRANS
|
||||
{
|
||||
//--- инфицируем «слабую» половину и грузим бактерии в слоты
|
||||
DoGeneTransfer();
|
||||
|
||||
for(int b = 0; b < popSize; b++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [b].c [c] = bact [b].c [c];
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Revision |
|
||||
//| Считывает a[i].f, обновляет cB/fB и продвигает автомат. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BEA::Revision()
|
||||
{
|
||||
//--- глобальный лучший (элитизм: лучшее не теряется при переносе)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(a [i].f > fB)
|
||||
{
|
||||
fB = a [i].f;
|
||||
ArrayCopy(cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
}
|
||||
|
||||
//--- первичная фиксация фитнеса бактерий
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
bact [i].f = a [i].f;
|
||||
|
||||
revision = true;
|
||||
phase = PH_MUT;
|
||||
segIdx = 0;
|
||||
cloneIdx = 0;
|
||||
transIdx = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(phase == PH_MUT)
|
||||
{
|
||||
//--- сохраняем фитнес оценённого среза клонов
|
||||
for(int b = 0; b < popSize; b++)
|
||||
clone [b * Nc + cloneIdx].f = a [b].f;
|
||||
|
||||
cloneIdx++;
|
||||
|
||||
//--- сегмент полностью оценён -> закрепляем лучший клон
|
||||
if(cloneIdx >= Nc)
|
||||
{
|
||||
for(int b = 0; b < popSize; b++)
|
||||
{
|
||||
int best = 0;
|
||||
double bf = clone [b * Nc + 0].f;
|
||||
for(int j = 1; j < Nc; j++)
|
||||
{
|
||||
double cf = clone [b * Nc + j].f;
|
||||
if(cf > bf)
|
||||
{
|
||||
bf = cf;
|
||||
best = j;
|
||||
}
|
||||
}
|
||||
|
||||
//--- закрепляем лучший мутант ТОЛЬКО если он превзошёл
|
||||
// инкумбента; иначе бактерия остаётся прежней (монотонность
|
||||
// мутации сохраняется без переоценки инкумбента клоном)
|
||||
if(bf > bact [b].f)
|
||||
{
|
||||
int bi = b * Nc + best;
|
||||
for(int c = 0; c < coords; c++)
|
||||
bact [b].c [c] = clone [bi].c [c];
|
||||
bact [b].f = bf;
|
||||
}
|
||||
}
|
||||
|
||||
cloneIdx = 0;
|
||||
segIdx++;
|
||||
|
||||
//--- все сегменты пройдены -> перенос генов (или новое поколение)
|
||||
if(segIdx >= Nseg)
|
||||
{
|
||||
segIdx = 0;
|
||||
if(nTrans > 0)
|
||||
{
|
||||
phase = PH_TRANS;
|
||||
transIdx = 0;
|
||||
}
|
||||
else
|
||||
phase = PH_MUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // PH_TRANS
|
||||
{
|
||||
//--- принимаем инфицированные генотипы (не-greedy)
|
||||
for(int b = 0; b < popSize; b++)
|
||||
bact [b].f = a [b].f;
|
||||
|
||||
transIdx++;
|
||||
if(transIdx >= nTrans)
|
||||
{
|
||||
phase = PH_MUT;
|
||||
segIdx = 0;
|
||||
cloneIdx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,349 @@
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
//| C_AO_BWOm |
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//———————————————————————————————————————————————————————————————————+
|
||||
|
||||
#include "#C_AO.mqh"
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Beluga Whale Optimization — МОДИФИЦИРОВАННАЯ версия. |
|
||||
//| |
|
||||
//| Общий принцип модификации: в оригинальной BWO каждая из трёх фаз |
|
||||
//| использует случайные множители, разыгранные ОДИН раз на агента |
|
||||
//| (r1..r7 — скаляры), домножающие целые векторы. Любой такой |
|
||||
//| скаляр-на-вектор запирает кандидата в низкоразмерное подпрост- |
|
||||
//| ранство. На бенче из N копий одной функции оптимум осесимметри- |
|
||||
//| чен, и это подпространство совпадает с главной диагональю, на |
|
||||
//| которой оптимум и лежит — алгоритм «считывает диагональ» даром, |
|
||||
//| причём эффект УСИЛИВАЕТСЯ с размерностью: покоординатный шум |
|
||||
//| Леви усредняется при greedy-приёмке по среднему фитнесу. |
|
||||
//| |
|
||||
//| BWOm заменяет скаляры-на-агента на ПОКООРДИНАТНУЮ случайность во |
|
||||
//| всех трёх фазах: |
|
||||
//| - разведка: r1, r2 на каждую пару; тяга к одноимённой паре |
|
||||
//| соседа (без общего скаляра-опоры и кросс-перестановки); |
|
||||
//| - эксплуатация: тяга к глобальному лучшему — покоординатная |
|
||||
//| интерполяция (r3 на каждую координату); масштаб-скаляр |
|
||||
//| r3*cB убран — именно он порождал луч origin->cB; |
|
||||
//| - падение кита: r5, r6 покоординатные. |
|
||||
//| Трёхфазная структура, балансовый фактор, вероятность падения |
|
||||
//| кита, полёт Леви и временное затухание C1/C2 сохранены. |
|
||||
//+------------------------------------------------------------------+
|
||||
class C_AO_BWOm : public C_AO
|
||||
{
|
||||
public:
|
||||
~C_AO_BWOm() {}
|
||||
C_AO_BWOm()
|
||||
{
|
||||
ao_name = "BWOm";
|
||||
ao_desc = "Beluga Whale Optimization (modified)";
|
||||
ao_link = "https://www.mql5.com/ru/articles/22686";
|
||||
|
||||
popSize = 20;
|
||||
KD = 1.5;
|
||||
|
||||
ArrayResize(params, 2);
|
||||
params [0].name = "popSize"; params [0].val = popSize;
|
||||
params [1].name = "KD"; params [1].val = KD;
|
||||
}
|
||||
|
||||
void SetParams()
|
||||
{
|
||||
popSize = (int)params [0].val;
|
||||
KD = params [1].val;
|
||||
|
||||
//--- предохранители
|
||||
if(popSize < 1)
|
||||
popSize = 1;
|
||||
if(KD < 0.0)
|
||||
KD = 0.0;
|
||||
}
|
||||
|
||||
bool Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0);
|
||||
|
||||
void Moving();
|
||||
void Revision();
|
||||
|
||||
//--- видимые параметры
|
||||
double KD; // интенсивность полёта Леви (оригинал: 0.05)
|
||||
|
||||
private:
|
||||
//--- snapshot для greedy acceptance
|
||||
double snap_c []; // [popSize * coords] — плоский буфер
|
||||
double snap_f []; // [popSize]
|
||||
|
||||
//--- счётчик итераций (для отношения T/Max_it)
|
||||
int epochs; // всего эпох (из Init)
|
||||
int epochsDen; // знаменатель для T/Max_it
|
||||
int epochNow; // номер текущей «боевой» итерации
|
||||
|
||||
//--- константа масштаба для полёта Леви (Mantegna, beta = 1.5)
|
||||
double levySigma;
|
||||
|
||||
//--- стандартное нормальное число (Box–Muller)
|
||||
double Gauss();
|
||||
//--- один отсчёт полёта Леви по координате
|
||||
double LevyStep();
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool C_AO_BWOm::Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0)
|
||||
{
|
||||
if(!StandardInit(rangeMinP, rangeMaxP, rangeStepP))
|
||||
return false;
|
||||
|
||||
//--- начальная случайная популяция в cP[] (попадёт в c[] на первом Moving)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].cP [c] = u.RNDfromCI(rangeMin [c], rangeMax [c]);
|
||||
|
||||
//--- внутренние буферы
|
||||
ArrayResize(snap_c, popSize * coords);
|
||||
ArrayResize(snap_f, popSize);
|
||||
|
||||
//--- счётчик итераций
|
||||
epochs = epochsP;
|
||||
epochsDen = (epochs > 1) ? epochs - 1 : 1;
|
||||
epochNow = 0;
|
||||
|
||||
//--- sigma для полёта Леви (Mantegna), beta = 1.5
|
||||
// значения гамма-функции посчитаны заранее, чтобы не зависеть
|
||||
// от наличия MathGamma:
|
||||
// Г(1 + beta) = Г(2.5) = 1.3293403881791
|
||||
// Г((1+beta)/2) = Г(1.25) = 0.9064024770554
|
||||
double beta = 1.5;
|
||||
double g1 = 1.3293403881791;
|
||||
double g2 = 0.9064024770554;
|
||||
levySigma = MathPow((g1 * MathSin(M_PI * beta / 2.0)) /
|
||||
(g2 * beta * MathPow(2.0, (beta - 1.0) / 2.0)),
|
||||
1.0 / beta); // ≈ 0.69655
|
||||
|
||||
return true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gauss — стандартное нормальное (Box–Muller) |
|
||||
//+------------------------------------------------------------------+
|
||||
double C_AO_BWOm::Gauss()
|
||||
{
|
||||
double u1 = u.RNDfromCI(0.0, 1.0);
|
||||
double u2 = u.RNDfromCI(0.0, 1.0);
|
||||
if(u1 < 1e-15)
|
||||
u1 = 1e-15;
|
||||
return MathSqrt(-2.0 * MathLog(u1)) * MathCos(2.0 * M_PI * u2);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| LevyStep — один отсчёт полёта Леви (Mantegna) |
|
||||
//+------------------------------------------------------------------+
|
||||
double C_AO_BWOm::LevyStep()
|
||||
{
|
||||
double uu = Gauss() * levySigma;
|
||||
double vv = Gauss();
|
||||
double av = MathAbs(vv);
|
||||
if(av < 1e-300)
|
||||
av = 1e-300;
|
||||
return KD * (uu / MathPow(av, 1.0 / 1.5));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving |
|
||||
//| |
|
||||
//| Структура итерации: |
|
||||
//| 1. snapshot текущей популяции; |
|
||||
//| 2. для каждого агента — балансовый фактор Bf и сосед RJ; |
|
||||
//| 3. выбор ветви: |
|
||||
//| Bf <= WF -> падение кита; |
|
||||
//| Bf > 0.5 -> разведка (честное парное плавание); |
|
||||
//| иначе -> эксплуатация (покоординатная тяга к cB); |
|
||||
//| 4. новый кандидат пишется в a[i].c. |
|
||||
//| Во всех ветвях случайность ПОКООРДИНАТНАЯ — нет скаляра на |
|
||||
//| агента, домножающего целый вектор. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BWOm::Moving()
|
||||
{
|
||||
//--- первый прогон: cP -> c, чтобы внешний цикл оценил FF
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = u.SeInDiSp(a [i].cP [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
return;
|
||||
}
|
||||
|
||||
//--- номер текущей итерации и отношение T/Max_it
|
||||
epochNow++;
|
||||
double tRatio = (double)epochNow / (double)epochsDen;
|
||||
if(tRatio > 1.0)
|
||||
tRatio = 1.0;
|
||||
|
||||
//--- snapshot текущей популяции
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
snap_c [i * coords + c] = a [i].c [c];
|
||||
snap_f [i] = a [i].f;
|
||||
}
|
||||
|
||||
//--- вероятность падения кита
|
||||
double WF = 0.1 - 0.05 * tRatio;
|
||||
|
||||
//--- движение
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
//--- балансовый фактор Bf = B0 * (1 - T/2Tmax)
|
||||
double Bf = (1.0 - 0.5 * tRatio) * u.RNDprobab();
|
||||
|
||||
//--- случайный сосед RJ != i
|
||||
int RJ = i;
|
||||
if(popSize > 1)
|
||||
while(RJ == i)
|
||||
RJ = u.RNDminusOne(popSize);
|
||||
|
||||
//================================================================
|
||||
if(Bf <= WF)
|
||||
{
|
||||
//--- ФАЗА 3: ПАДЕНИЕ КИТА (whale fall) — модификация
|
||||
// Оригинал: v = r5*xi - r6*xr + step, r5/r6 — скаляры на
|
||||
// агента -> скелет заперт в плоскости (xi, xr), на стянутой
|
||||
// диагонали — в линию. BWOm: r5, r6 покоординатные.
|
||||
// r7 (магнитуда шага) оставлен на агента — равномерный
|
||||
// масштаб шага не запирает кандидата.
|
||||
double r7 = u.RNDprobab();
|
||||
double C2 = 2.0 * (double)popSize * WF;
|
||||
double decay = MathExp(-C2 * tRatio);
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double r5c = u.RNDprobab();
|
||||
double r6c = u.RNDprobab();
|
||||
double step = r7 * (rangeMax [c] - rangeMin [c]) * decay;
|
||||
double v = r5c * snap_c [i * coords + c] -
|
||||
r6c * snap_c [RJ * coords + c] + step;
|
||||
a [i].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
//================================================================
|
||||
else
|
||||
if(Bf > 0.5)
|
||||
{
|
||||
//--- ФАЗА 1: РАЗВЕДКА — честное парное плавание (модификация)
|
||||
// каждая пара координат (dA, dB) тянется к своей одноимённой
|
||||
// паре соседа RJ; r1, r2 разыгрываются на КАЖДУЮ пару.
|
||||
// Ни общего скаляра-опоры, ни кросс-перестановки измерений.
|
||||
|
||||
//--- незатронутые координаты остаются прежними
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = snap_c [i * coords + c];
|
||||
|
||||
int pairs = coords / 2;
|
||||
|
||||
for(int j = 0; j < pairs; j++)
|
||||
{
|
||||
int dA = 2 * j; // x-координата пары
|
||||
int dB = 2 * j + 1; // y-координата пары
|
||||
|
||||
double r1 = u.RNDprobab();
|
||||
double r2 = u.RNDprobab();
|
||||
double ang = 2.0 * M_PI * r2;
|
||||
double sinA = MathSin(ang);
|
||||
double cosA = MathCos(ang);
|
||||
|
||||
double xA = snap_c [i * coords + dA];
|
||||
double xB = snap_c [i * coords + dB];
|
||||
double refA = snap_c [RJ * coords + dA];
|
||||
double refB = snap_c [RJ * coords + dB];
|
||||
|
||||
double vA = xA + (refA - xA) * (r1 + 1.0) * sinA;
|
||||
double vB = xB + (refB - xB) * (r1 + 1.0) * cosA;
|
||||
a [i].c [dA] = u.SeInDiSp(vA, rangeMin [dA], rangeMax [dA], rangeStep [dA]);
|
||||
a [i].c [dB] = u.SeInDiSp(vB, rangeMin [dB], rangeMax [dB], rangeStep [dB]);
|
||||
}
|
||||
}
|
||||
//================================================================
|
||||
else
|
||||
{
|
||||
//--- ФАЗА 2: ЭКСПЛУАТАЦИЯ (охота, полёт Леви) — модификация
|
||||
// Оригинал: v = r3*cB - r4*xi + C1*LF*(xr-xi), r3 — скаляр
|
||||
// на агента. Слагаемое r3*cB — масштабированный осесиммет-
|
||||
// ричный глобальный лучший: кандидат скользит по лучу
|
||||
// origin->cB (главная диагональ на бенче из копий функции).
|
||||
// На больших размерностях покоординатный шум Леви усред-
|
||||
// няется при greedy-приёмке по среднему фитнесу, и отбор
|
||||
// оптимизирует фактически одномерное сканирование диагонали.
|
||||
// BWOm: тяга к лучшему — покоординатная интерполяция (r3 на
|
||||
// КАЖДУЮ координату), скаляр-масштаб r3*cB убран.
|
||||
// C1 (затухание Леви) оставлен на агента: равномерный
|
||||
// масштаб покоординатно-случайного вектора Леви не запирает
|
||||
// кандидата в подпространство.
|
||||
double r4 = u.RNDprobab();
|
||||
double C1 = 2.0 * r4 * (1.0 - tRatio);
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double r3c = u.RNDprobab();
|
||||
double xi = snap_c [i * coords + c];
|
||||
double xr = snap_c [RJ * coords + c];
|
||||
double Lv = LevyStep();
|
||||
double v = xi + r3c * (cB [c] - xi) + C1 * Lv * (xr - xi);
|
||||
a [i].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Revision |
|
||||
//| |
|
||||
//| Стандартное обновление fB/cB + greedy acceptance: если новый |
|
||||
//| фитнес хуже снапшота — откат координат и фитнеса агента. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_BWOm::Revision()
|
||||
{
|
||||
//--- обновление личных и глобального лучших
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(a [i].f > a [i].fB)
|
||||
{
|
||||
a [i].fB = a [i].f;
|
||||
ArrayCopy(a [i].cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
if(a [i].f > fB)
|
||||
{
|
||||
fB = a [i].f;
|
||||
ArrayCopy(cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
}
|
||||
|
||||
if(!revision)
|
||||
{
|
||||
revision = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//--- greedy acceptance: rollback если стало хуже
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(a [i].f < snap_f [i])
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = snap_c [i * coords + c];
|
||||
a [i].f = snap_f [i];
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,380 @@
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
//| C_AO_COA_Coyote|
|
||||
//| Copyright 2007-2025, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
#include "#C_AO.mqh"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Coyote Optimization Algorithm (COA). |
|
||||
//| Pierezan J., Coelho L.S. "Coyote Optimization Algorithm: A new |
|
||||
//| metaheuristic for global optimization problems", IEEE CEC 2018. |
|
||||
//| |
|
||||
//| Структура: популяция разбита на nPacks стай по nCoy койотов. |
|
||||
//| За эпоху в каждой стае: |
|
||||
//| 1. определяется альфа (лучший по фитнесу, Eq. 5); |
|
||||
//| 2. считается «социальная тенденция» — покоординатная медиана |
|
||||
//| стаи (Eq. 6); |
|
||||
//| 3. каждый койот делает социальный ход (Eq. 12): |
|
||||
//| new = x + r1*(alpha - x_rc1) + r2*(tend - x_rc2), |
|
||||
//| r1, r2 — СКАЛЯРЫ на агента (как в оригинале); |
|
||||
//| 4. рождается щенок (Eq. 7, Alg. 1): бинарный кроссовер двух |
|
||||
//| случайных родителей + равномерный шум по части координат; |
|
||||
//| 5. принятие — только при строгом улучшении (Eq. 14). |
|
||||
//| Редкий обмен койотами между стаями (Eq. 4, p_leave) и счётчик |
|
||||
//| возраста (щенок обнуляет возраст слота). |
|
||||
//| |
|
||||
//| АДАПТАЦИЯ К БАТЧЕВОЙ СХЕМЕ СТЕНДА (Moving/Revision): |
|
||||
//| 1. Оригинал последовательный: каждый новый койот оценивается |
|
||||
//| сразу, плюс отдельная оценка щенка — nCoy+1 вызовов FF на |
|
||||
//| стаю за «год». Здесь щенок занимает слот ХУДШЕГО койота стаи |
|
||||
//| (при равенстве фитнеса — старшего по возрасту); социальный |
|
||||
//| ход этого койота в текущую эпоху пропускается. Итог: ровно |
|
||||
//| popSize вызовов FF за эпоху, бюджет расходуется честно. |
|
||||
//| 2. Приживание щенка в оригинале: замена старейшего среди тех, |
|
||||
//| кто хуже щенка. Здесь слот выбран заранее (худший/старший), |
|
||||
//| щенок принимается, если строго лучше него — поведенчески |
|
||||
//| эквивалентное приближение в рамках greedy-acceptance. |
|
||||
//| 3. Все ходы эпохи считаются от снапшота популяции (в оригинале |
|
||||
//| обновления внутри стаи частично последовательные). |
|
||||
//| |
|
||||
//| ВНИМАНИЕ (для off-diagonal проверки): в социальном ходе r1 и r2 |
|
||||
//| — скаляры, домножающие целые векторы разностей. Это потенциаль- |
|
||||
//| ный кандидат на «диагональный чит» на бенче из копий функции — |
|
||||
//| проверить составным тестом с |x_norm - y_norm| > 0.3. |
|
||||
//+------------------------------------------------------------------+
|
||||
class C_AO_COA_Coyote : public C_AO
|
||||
{
|
||||
public:
|
||||
~C_AO_COA_Coyote() {}
|
||||
C_AO_COA_Coyote()
|
||||
{
|
||||
ao_name = "COA(Coyote)";
|
||||
ao_desc = "Coyote Optimization Algorithm";
|
||||
ao_link = "https://www.mql5.com/ru/articles/23053";
|
||||
|
||||
popSize = 20;
|
||||
nCoy = 5;
|
||||
|
||||
ArrayResize(params, 2);
|
||||
params [0].name = "popSize";
|
||||
params [0].val = popSize;
|
||||
params [1].name = "nCoy";
|
||||
params [1].val = nCoy;
|
||||
|
||||
nPacks = popSize / nCoy;
|
||||
}
|
||||
|
||||
void SetParams()
|
||||
{
|
||||
popSize = (int)params [0].val;
|
||||
nCoy = (int)params [1].val;
|
||||
|
||||
nPacks = popSize / nCoy;
|
||||
}
|
||||
|
||||
bool Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0);
|
||||
|
||||
void Moving();
|
||||
void Revision();
|
||||
|
||||
//--- видимые параметры
|
||||
int nCoy; // койотов в стае (оригинал: 5)
|
||||
|
||||
private:
|
||||
int nPacks; // число стай = popSize / nCoy
|
||||
double pLeave; // вероятность обмена между стаями: 0.005*nCoy^2
|
||||
double probPup; // (1 - Ps)/2, Ps = 1/coords
|
||||
|
||||
int packs []; // [nPacks * nCoy] — индексы агентов по стаям
|
||||
int ages []; // [popSize] — возраст койота
|
||||
bool isPup []; // [popSize] — слот щенка в текущую эпоху
|
||||
|
||||
//--- snapshot для greedy acceptance
|
||||
double snap_c []; // [popSize * coords]
|
||||
double snap_f []; // [popSize]
|
||||
|
||||
//--- рабочие буферы
|
||||
double medBuf []; // [nCoy] — для медианы
|
||||
double tend []; // [coords] — социальная тенденция стаи
|
||||
int pdr []; // [coords] — перестановка измерений (щенок)
|
||||
int mask []; // [coords] — 0: шум, 1: родитель 1, 2: родитель 2
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool C_AO_COA_Coyote::Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0)
|
||||
{
|
||||
if(!StandardInit(rangeMinP, rangeMaxP, rangeStepP))
|
||||
return false;
|
||||
|
||||
//--- начальная случайная популяция в cP[] (Eq. 2)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].cP [c] = u.RNDfromCI(rangeMin [c], rangeMax [c]);
|
||||
|
||||
//--- параметры, зависящие от nCoy и coords
|
||||
pLeave = 0.005 * (double)nCoy * (double)nCoy; // Eq. 4
|
||||
probPup = (coords > 0) ? (1.0 - 1.0 / (double)coords) * 0.5 : 0.0; // (1-Ps)/2
|
||||
|
||||
//--- буферы
|
||||
ArrayResize(snap_c, popSize * coords);
|
||||
ArrayResize(snap_f, popSize);
|
||||
ArrayResize(packs, nPacks * nCoy);
|
||||
ArrayResize(ages, popSize);
|
||||
ArrayResize(isPup, popSize);
|
||||
ArrayResize(medBuf, nCoy);
|
||||
ArrayResize(tend, coords);
|
||||
ArrayResize(pdr, coords);
|
||||
ArrayResize(mask, coords);
|
||||
|
||||
ArrayInitialize(ages, 0);
|
||||
ArrayInitialize(isPup, false);
|
||||
|
||||
//--- случайное распределение койотов по стаям (Fisher–Yates)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
packs [i] = i;
|
||||
for(int j = popSize - 1; j > 0; j--)
|
||||
{
|
||||
int r = u.RNDminusOne(j + 1);
|
||||
int tmp = packs [j];
|
||||
packs [j] = packs [r];
|
||||
packs [r] = tmp;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving |
|
||||
//| |
|
||||
//| Структура эпохи: |
|
||||
//| 1. snapshot популяции; |
|
||||
//| 2. редкий обмен койотами между стаями (Eq. 4); |
|
||||
//| 3. для каждой стаи: альфа, тенденция-медиана, слот щенка; |
|
||||
//| 4. социальные ходы (Eq. 12) для всех, кроме слота щенка; |
|
||||
//| 5. в слот щенка — кроссовер двух родителей + шум (Alg. 1). |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_COA_Coyote::Moving()
|
||||
{
|
||||
//--- первый прогон: cP -> c, чтобы внешний цикл оценил FF
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = u.SeInDiSp(a [i].cP [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
return;
|
||||
}
|
||||
|
||||
//--- snapshot текущей популяции
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
snap_c [i * coords + c] = a [i].c [c];
|
||||
snap_f [i] = a [i].f;
|
||||
}
|
||||
|
||||
//--- обмен койотами между стаями (Eq. 4)
|
||||
if(nPacks > 1 && u.RNDprobab() < pLeave)
|
||||
{
|
||||
int p1 = u.RNDminusOne(nPacks);
|
||||
int p2 = p1;
|
||||
while(p2 == p1)
|
||||
p2 = u.RNDminusOne(nPacks);
|
||||
|
||||
int c1 = u.RNDminusOne(nCoy);
|
||||
int c2 = u.RNDminusOne(nCoy);
|
||||
|
||||
int tmp = packs [p1 * nCoy + c1];
|
||||
packs [p1 * nCoy + c1] = packs [p2 * nCoy + c2];
|
||||
packs [p2 * nCoy + c2] = tmp;
|
||||
}
|
||||
|
||||
ArrayInitialize(isPup, false);
|
||||
|
||||
//--- операции внутри каждой стаи
|
||||
for(int p = 0; p < nPacks; p++)
|
||||
{
|
||||
int base = p * nCoy;
|
||||
|
||||
//--- альфа стаи (Eq. 5): максимум фитнеса (стенд максимизирует)
|
||||
int aIdx = packs [base];
|
||||
for(int k = 1; k < nCoy; k++)
|
||||
{
|
||||
int idx = packs [base + k];
|
||||
if(snap_f [idx] > snap_f [aIdx])
|
||||
aIdx = idx;
|
||||
}
|
||||
|
||||
//--- социальная тенденция (Eq. 6): покоординатная медиана стаи
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
for(int k = 0; k < nCoy; k++)
|
||||
medBuf [k] = snap_c [packs [base + k] * coords + c];
|
||||
ArraySort(medBuf);
|
||||
tend [c] = (nCoy % 2 == 1) ? medBuf [nCoy / 2]
|
||||
: 0.5 * (medBuf [nCoy / 2 - 1] + medBuf [nCoy / 2]);
|
||||
}
|
||||
|
||||
//--- слот щенка: худший фитнес, при равенстве — старший возраст
|
||||
int wK = 0;
|
||||
for(int k = 1; k < nCoy; k++)
|
||||
{
|
||||
int idx = packs [base + k];
|
||||
int wIdx = packs [base + wK];
|
||||
if(snap_f [idx] < snap_f [wIdx] ||
|
||||
(snap_f [idx] == snap_f [wIdx] && ages [idx] > ages [wIdx]))
|
||||
wK = k;
|
||||
}
|
||||
int pupIdx = packs [base + wK];
|
||||
isPup [pupIdx] = true;
|
||||
|
||||
//--- движение койотов стаи
|
||||
for(int k = 0; k < nCoy; k++)
|
||||
{
|
||||
int i = packs [base + k];
|
||||
|
||||
if(i == pupIdx)
|
||||
{
|
||||
//--- РОЖДЕНИЕ ЩЕНКА (Eq. 7, Alg. 1) -------------------------
|
||||
// два случайных различных родителя из стаи
|
||||
int k1 = u.RNDminusOne(nCoy);
|
||||
int k2 = k1;
|
||||
while(k2 == k1)
|
||||
k2 = u.RNDminusOne(nCoy);
|
||||
int par1 = packs [base + k1];
|
||||
int par2 = packs [base + k2];
|
||||
|
||||
//--- перестановка измерений (Fisher–Yates)
|
||||
for(int c = 0; c < coords; c++)
|
||||
pdr [c] = c;
|
||||
|
||||
for(int j = coords - 1; j > 0; j--)
|
||||
{
|
||||
int r = u.RNDminusOne(j + 1);
|
||||
int tmp = pdr [j];
|
||||
pdr [j] = pdr [r];
|
||||
pdr [r] = tmp;
|
||||
}
|
||||
|
||||
//--- маска: гарантированно по одной координате от каждого
|
||||
// родителя, остальные — родитель 1 / родитель 2 / шум
|
||||
ArrayInitialize(mask, 0);
|
||||
mask [pdr [0]] = 1;
|
||||
if(coords > 1)
|
||||
mask [pdr [1]] = 2;
|
||||
for(int j = 2; j < coords; j++)
|
||||
{
|
||||
double r = u.RNDprobab();
|
||||
if(r < probPup)
|
||||
mask [pdr [j]] = 1;
|
||||
else
|
||||
if(r > 1.0 - probPup)
|
||||
mask [pdr [j]] = 2;
|
||||
// иначе 0 — равномерный шум по координате
|
||||
}
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double v;
|
||||
if(mask [c] == 1)
|
||||
v = snap_c [par1 * coords + c];
|
||||
else
|
||||
if(mask [c] == 2)
|
||||
v = snap_c [par2 * coords + c];
|
||||
else
|
||||
v = u.RNDfromCI(rangeMin [c], rangeMax [c]);
|
||||
|
||||
a [i].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- СОЦИАЛЬНЫЙ ХОД (Eq. 12) --------------------------------
|
||||
// rc1, rc2 — различные, не совпадающие с k
|
||||
int k1 = k;
|
||||
while(k1 == k)
|
||||
k1 = u.RNDminusOne(nCoy);
|
||||
int k2 = k;
|
||||
while(k2 == k || k2 == k1)
|
||||
k2 = u.RNDminusOne(nCoy);
|
||||
int rc1 = packs [base + k1];
|
||||
int rc2 = packs [base + k2];
|
||||
|
||||
//--- r1, r2 — скаляры на агента, как в оригинале
|
||||
double r1 = u.RNDprobab();
|
||||
double r2 = u.RNDprobab();
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double v = snap_c [i * coords + c] +
|
||||
r1 * (snap_c [aIdx * coords + c] - snap_c [rc1 * coords + c]) +
|
||||
r2 * (tend [c] - snap_c [rc2 * coords + c]);
|
||||
|
||||
a [i].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
} // k
|
||||
} // p
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Revision |
|
||||
//| |
|
||||
//| Стандартное обновление fB/cB + адаптация (Eq. 14): кандидат |
|
||||
//| принимается только при СТРОГОМ улучшении, иначе откат к |
|
||||
//| снапшоту (касается и социальных ходов, и щенка). Возраст всех |
|
||||
//| койотов растёт на 1 за эпоху; прижившийся щенок обнуляет |
|
||||
//| возраст слота. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_COA_Coyote::Revision()
|
||||
{
|
||||
//--- обновление личных и глобального лучших
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(a [i].f > a [i].fB)
|
||||
{
|
||||
a [i].fB = a [i].f;
|
||||
ArrayCopy(a [i].cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
if(a [i].f > fB)
|
||||
{
|
||||
fB = a [i].f;
|
||||
ArrayCopy(cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
}
|
||||
|
||||
if(!revision)
|
||||
{
|
||||
revision = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//--- адаптация (Eq. 14): принятие только при строгом улучшении
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
bool accepted = (a [i].f > snap_f [i]);
|
||||
|
||||
if(!accepted)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = snap_c [i * coords + c];
|
||||
a [i].f = snap_f [i];
|
||||
}
|
||||
|
||||
//--- возраст
|
||||
ages [i]++;
|
||||
if(isPup [i] && accepted)
|
||||
ages [i] = 0;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,326 @@
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
//| C_AO_CVO |
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//———————————————————————————————————————————————————————————————————+
|
||||
|
||||
#include "#C_AO.mqh"
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
struct S_CVO_Patient
|
||||
{
|
||||
double c [];
|
||||
double f;
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
class C_AO_CVO : public C_AO
|
||||
{
|
||||
public:
|
||||
~C_AO_CVO() {}
|
||||
C_AO_CVO()
|
||||
{
|
||||
ao_name = "CVO";
|
||||
ao_desc = "Corona Virus Optimization";
|
||||
ao_link = "https://www.mql5.com/ru/articles/22887";
|
||||
|
||||
popSize = 50; // бюджет FE на эпоху (= кандидатов за проход)
|
||||
nPop = 200; // потолок инфекционной популяции
|
||||
basePop = 5; // стартовая инфекционная популяция
|
||||
R0 = 5; // потомков-восприимчивых на одного носителя
|
||||
rho = 0.1; // контактность: общий множитель масштаба λ
|
||||
|
||||
ArrayResize(params, 5);
|
||||
params [0].name = "popSize"; params [0].val = popSize;
|
||||
params [1].name = "nPop"; params [1].val = nPop;
|
||||
params [2].name = "basePop"; params [2].val = basePop;
|
||||
params [3].name = "R0"; params [3].val = R0;
|
||||
params [4].name = "rho"; params [4].val = rho;
|
||||
}
|
||||
|
||||
void SetParams()
|
||||
{
|
||||
popSize = (int)params [0].val;
|
||||
nPop = (int)params [1].val;
|
||||
basePop = (int)params [2].val;
|
||||
R0 = (int)params [3].val;
|
||||
rho = params [4].val;
|
||||
|
||||
//--- предохранители
|
||||
if(popSize < 1) popSize = 1;
|
||||
if(nPop < 1) nPop = 1;
|
||||
if(R0 < 1) R0 = 1;
|
||||
if(rho < 0.0) rho = 0.0;
|
||||
if(basePop < 1) basePop = 1;
|
||||
if(basePop > popSize) basePop = popSize; // пул засевается из 1-го батча
|
||||
if(basePop > nPop) basePop = nPop;
|
||||
}
|
||||
|
||||
bool Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0);
|
||||
|
||||
void Moving();
|
||||
void Revision();
|
||||
|
||||
//--- видимые параметры
|
||||
int nPop; // потолок инфекционной популяции
|
||||
int basePop; // стартовая инфекционная популяция
|
||||
int R0; // потомков на носителя
|
||||
double rho; // множитель масштаба λ
|
||||
|
||||
private:
|
||||
//--- инфекционный пул (массив структур: координаты + фитнес вместе)
|
||||
S_CVO_Patient inf []; // [nPop]
|
||||
int infCount; // текущий размер пула (<= nPop)
|
||||
|
||||
//--- привязка слота-кандидата к носителю
|
||||
int parentOf []; // [popSize]
|
||||
|
||||
//--- временный пул пересборки
|
||||
S_CVO_Patient tmp []; // [nPop + popSize]
|
||||
|
||||
//--- стандартное нормальное (Box-Muller), Eq.3
|
||||
double Gauss();
|
||||
//--- индексная сортировка по убыванию f
|
||||
void ArgSortDesc(const double &f [], int &idx [], const int count);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool C_AO_CVO::Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0)
|
||||
{
|
||||
if(!StandardInit(rangeMinP, rangeMaxP, rangeStepP))
|
||||
return false;
|
||||
|
||||
//--- стартовый случайный батч в cP[] (оценится на первом проходе)
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].cP [c] = u.RNDfromCI(rangeMin [c], rangeMax [c]);
|
||||
|
||||
//--- инфекционный пул и временный пул (массивы структур)
|
||||
ArrayResize(inf, nPop);
|
||||
for(int i = 0; i < nPop; i++)
|
||||
ArrayResize(inf [i].c, coords);
|
||||
|
||||
ArrayResize(tmp, nPop + popSize);
|
||||
for(int i = 0; i < nPop + popSize; i++)
|
||||
ArrayResize(tmp [i].c, coords);
|
||||
|
||||
ArrayResize(parentOf, popSize);
|
||||
infCount = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving |
|
||||
//| |
|
||||
//| Первый проход: случайный батч cP -> c (стенд его оценит, далее |
|
||||
//| Revision засеет инфекционный пул лучшими basePop особями). |
|
||||
//| Боевой проход: каждый слот-кандидат = восприимчивый, рождённый |
|
||||
//| носителем p = (k/R0) % infCount возмущением λ (покоординатно). |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_CVO::Moving()
|
||||
{
|
||||
//--- первый прогон: cP -> c
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = u.SeInDiSp(a [i].cP [c], rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
return;
|
||||
}
|
||||
|
||||
//--- генерация кандидатов-восприимчивых
|
||||
for(int k = 0; k < popSize; k++)
|
||||
{
|
||||
int denom = infCount > 0 ? infCount : 1; // защита от %0
|
||||
int p = (k / R0) % denom; // носитель данного слота
|
||||
parentOf [k] = p;
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double phi = Gauss(); // Eq.3, [D1] свой на координату
|
||||
double frac = (double)(infCount + k) / (double)nPop; // I/N, Eq.1*Eq.2, [D3]
|
||||
if(frac > 1.0)
|
||||
frac = 1.0;
|
||||
double lam = rho * phi * frac; // абсолютный шаг, ТОЧНО по статье (Eq.1*2*3)
|
||||
double v = inf [p].c [c] + lam * (rangeMax [c] - rangeMin [c]);
|
||||
a [k].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Revision |
|
||||
//| |
|
||||
//| 1. обновление личных и глобального лучших по кандидатам; |
|
||||
//| 2. первый проход: посев пула лучшими basePop особями; |
|
||||
//| 3. LocalBest эпохи; решение замена/рост пула; |
|
||||
//| 4. приёмка восприимчивых (иммунитет >= носителя); |
|
||||
//| 5. отсечение пула до nPop по убыванию f (выздоровление). |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_CVO::Revision()
|
||||
{
|
||||
//--- сохранить прежний глобальный лучший ДО обновления (для решения замена/рост)
|
||||
double fB_prev = fB;
|
||||
|
||||
//--- 1) обновление лучших
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(!MathIsValidNumber(a [i].f)) // нечисло не должно отравлять лучших/пул
|
||||
continue;
|
||||
if(a [i].f > a [i].fB)
|
||||
{
|
||||
a [i].fB = a [i].f;
|
||||
ArrayCopy(a [i].cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
if(a [i].f > fB)
|
||||
{
|
||||
fB = a [i].f;
|
||||
ArrayCopy(cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
}
|
||||
|
||||
//--- 2) первый проход: посев инфекционного пула лучшими basePop
|
||||
if(!revision)
|
||||
{
|
||||
int idx [];
|
||||
double af [];
|
||||
ArrayResize(idx, popSize);
|
||||
ArrayResize(af, popSize);
|
||||
for(int i = 0; i < popSize; i++) af [i] = a [i].f;
|
||||
|
||||
ArgSortDesc(af, idx, popSize);
|
||||
|
||||
infCount = basePop; // basePop <= popSize (зажато в SetParams)
|
||||
for(int n = 0; n < infCount; n++)
|
||||
{
|
||||
int s = idx [n];
|
||||
ArrayCopy(inf [n].c, a [s].c, 0, 0, coords);
|
||||
inf [n].f = a [s].f;
|
||||
}
|
||||
|
||||
revision = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//--- 3) лучший кандидат эпохи и решение замена/рост
|
||||
double localBest = -DBL_MAX;
|
||||
for(int i = 0; i < popSize; i++)
|
||||
if(MathIsValidNumber(a [i].f) && a [i].f > localBest)
|
||||
localBest = a [i].f;
|
||||
|
||||
bool improved = (localBest > fB_prev);
|
||||
|
||||
//--- 4) сборка обновлённого пула во временный пул (предвыделен в Init)
|
||||
int cnt = 0;
|
||||
|
||||
if(!improved)
|
||||
{
|
||||
//--- рост: сначала весь прежний пул
|
||||
for(int n = 0; n < infCount; n++)
|
||||
{
|
||||
ArrayCopy(tmp [cnt].c, inf [n].c, 0, 0, coords);
|
||||
tmp [cnt].f = inf [n].f;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
//--- принятые восприимчивые: иммунитет не лучше носителя -> заразился
|
||||
// (читаем inf[p].f ДО перезаписи пула — наложения нет)
|
||||
for(int k = 0; k < popSize; k++)
|
||||
{
|
||||
int p = parentOf [k];
|
||||
if(MathIsValidNumber(a [k].f) && a [k].f >= inf [p].f)
|
||||
{
|
||||
ArrayCopy(tmp [cnt].c, a [k].c, 0, 0, coords);
|
||||
tmp [cnt].f = a [k].f;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
//--- защита: при замене с пустым набором сохраняем прежний пул
|
||||
if(cnt == 0)
|
||||
return;
|
||||
|
||||
//--- 5) отсечение до nPop (выздоровление/смерть слабейших)
|
||||
if(cnt > nPop)
|
||||
{
|
||||
int idx [];
|
||||
double tf [];
|
||||
ArrayResize(idx, cnt);
|
||||
ArrayResize(tf, cnt);
|
||||
for(int n = 0; n < cnt; n++)
|
||||
tf [n] = tmp [n].f;
|
||||
|
||||
ArgSortDesc(tf, idx, cnt);
|
||||
for(int n = 0; n < nPop; n++)
|
||||
{
|
||||
int s = idx [n];
|
||||
ArrayCopy(inf [n].c, tmp [s].c, 0, 0, coords);
|
||||
inf [n].f = tmp [s].f;
|
||||
}
|
||||
infCount = nPop;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int n = 0; n < cnt; n++)
|
||||
{
|
||||
ArrayCopy(inf [n].c, tmp [n].c, 0, 0, coords);
|
||||
inf [n].f = tmp [n].f;
|
||||
}
|
||||
infCount = cnt;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gauss — стандартное нормальное (Box-Muller) |
|
||||
//+------------------------------------------------------------------+
|
||||
double C_AO_CVO::Gauss()
|
||||
{
|
||||
double u1 = u.RNDfromCI(0.0, 1.0);
|
||||
double u2 = u.RNDfromCI(0.0, 1.0);
|
||||
if(u1 < 1e-15)
|
||||
u1 = 1e-15; // защита от ln(0)
|
||||
return MathSqrt(-2.0 * MathLog(u1)) * MathCos(2.0 * M_PI * u2);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| ArgSortDesc — порядок индексов по убыванию f |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_CVO::ArgSortDesc(const double &f [], int &idx [], const int count)
|
||||
{
|
||||
for(int i = 0; i < count; i++)
|
||||
idx [i] = i;
|
||||
|
||||
for(int i = 0; i < count - 1; i++)
|
||||
{
|
||||
int b = i;
|
||||
for(int j = i + 1; j < count; j++)
|
||||
if(f [idx [j]] > f [idx [b]])
|
||||
b = j;
|
||||
if(b != i)
|
||||
{
|
||||
int t = idx [i];
|
||||
idx [i] = idx [b];
|
||||
idx [b] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,433 @@
|
||||
//+——————————————————————————————————————————————————————————————————+
|
||||
//| C_AO_NBE |
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//———————————————————————————————————————————————————————————————————+
|
||||
|
||||
#include "#C_AO.mqh"
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
struct S_Bacteroid
|
||||
{
|
||||
double c []; // генотип (валидные координаты)
|
||||
double f; // фитнес
|
||||
double E; // энергия
|
||||
|
||||
void Init(int coords)
|
||||
{
|
||||
ArrayResize(c, coords);
|
||||
f = -DBL_MAX;
|
||||
E = 0.0;
|
||||
}
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
class C_AO_NBE : public C_AO
|
||||
{
|
||||
public:
|
||||
~C_AO_NBE() {}
|
||||
C_AO_NBE()
|
||||
{
|
||||
ao_name = "NBE";
|
||||
ao_desc = "Numaoka Bacterial Evolution";
|
||||
ao_link = "https://www.mql5.com/ru/articles/23267";
|
||||
|
||||
popSize = 30; // число бактероидов
|
||||
stepSize = 0.1; // стартовый масштаб движения (доля диапазона)
|
||||
pPlasmid = 0.1; // вероятность плазмидного переноса на бактероид/эпоху
|
||||
transFrac = 0.2; // длина плазмиды как доля coords (0..1]
|
||||
cost = 0.5; // метаболическая стоимость (приход в [0,1])
|
||||
pDeath = 0.0005; // «средовая» вероятность гибели на бактероид/эпоху
|
||||
|
||||
ArrayResize(params, 6);
|
||||
params [0].name = "popSize"; params [0].val = popSize;
|
||||
params [1].name = "stepSize"; params [1].val = stepSize;
|
||||
params [2].name = "pPlasmid"; params [2].val = pPlasmid;
|
||||
params [3].name = "transFrac"; params [3].val = transFrac;
|
||||
params [4].name = "cost"; params [4].val = cost;
|
||||
params [5].name = "pDeath"; params [5].val = pDeath;
|
||||
}
|
||||
|
||||
void SetParams()
|
||||
{
|
||||
popSize = (int)params [0].val;
|
||||
stepSize = params [1].val;
|
||||
pPlasmid = params [2].val;
|
||||
transFrac = params [3].val;
|
||||
cost = params [4].val;
|
||||
pDeath = params [5].val;
|
||||
|
||||
//--- предохранители
|
||||
if(popSize < 1)
|
||||
popSize = 1;
|
||||
if(stepSize <= 0.0)
|
||||
stepSize = 0.001;
|
||||
if(pPlasmid < 0.0)
|
||||
pPlasmid = 0.0;
|
||||
if(pPlasmid > 1.0)
|
||||
pPlasmid = 1.0;
|
||||
if(transFrac <= 0.0)
|
||||
transFrac = 0.01;
|
||||
if(transFrac > 1.0)
|
||||
transFrac = 1.0;
|
||||
if(cost < 0.0)
|
||||
cost = 0.0;
|
||||
if(pDeath < 0.0)
|
||||
pDeath = 0.0;
|
||||
if(pDeath > 1.0)
|
||||
pDeath = 1.0;
|
||||
}
|
||||
|
||||
bool Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0);
|
||||
|
||||
void Moving();
|
||||
void Revision();
|
||||
|
||||
//--- видимые параметры
|
||||
double stepSize; // стартовый масштаб движения
|
||||
double pPlasmid; // вероятность переноса
|
||||
double transFrac; // доля coords для плазмиды
|
||||
double cost; // метаболическая стоимость
|
||||
double pDeath; // средовая гибель
|
||||
|
||||
private:
|
||||
//--- данные (массивы структур)
|
||||
S_Bacteroid bro []; // [popSize] — бактероиды
|
||||
int actType []; // [popSize] 0=движение, 1=перенос (на эпоху)
|
||||
int allIdx []; // [popSize] — 0..popSize-1
|
||||
int living []; // [popSize] — живые в текущем Revision
|
||||
|
||||
int transLen; // длина плазмиды (из transFrac)
|
||||
|
||||
//--- прогресс прогона (для отжига шага)
|
||||
int epochsDen;
|
||||
int epochNow;
|
||||
|
||||
//--- константы
|
||||
double E0; // стартовая энергия
|
||||
double Emax; // потолок энергии
|
||||
double STEP_MIN_RATIO;
|
||||
|
||||
//--- вспомогательные
|
||||
double Gauss();
|
||||
double StepNow();
|
||||
int RouletteByE(int &pool [], int n, int exclude);
|
||||
void Respawn(int i);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Init |
|
||||
//+------------------------------------------------------------------+
|
||||
bool C_AO_NBE::Init(const double &rangeMinP [],
|
||||
const double &rangeMaxP [],
|
||||
const double &rangeStepP [],
|
||||
const int epochsP = 0)
|
||||
{
|
||||
if(!StandardInit(rangeMinP, rangeMaxP, rangeStepP))
|
||||
return false;
|
||||
|
||||
//--- длина плазмиды
|
||||
transLen = (int)MathRound(transFrac * coords);
|
||||
if(transLen < 1)
|
||||
transLen = 1;
|
||||
if(transLen > coords)
|
||||
transLen = coords;
|
||||
|
||||
//--- прогресс / константы
|
||||
epochsDen = (epochsP > 1) ? epochsP - 1 : 1;
|
||||
epochNow = 0;
|
||||
E0 = 1.0;
|
||||
Emax = 5.0;
|
||||
STEP_MIN_RATIO = 0.025;
|
||||
|
||||
//--- буферы
|
||||
ArrayResize(bro, popSize);
|
||||
ArrayResize(actType, popSize);
|
||||
ArrayResize(allIdx, popSize);
|
||||
ArrayResize(living, popSize);
|
||||
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
bro [i].Init(coords);
|
||||
allIdx [i] = i;
|
||||
}
|
||||
|
||||
//--- стартовая популяция
|
||||
for(int i = 0; i < popSize; i++)
|
||||
Respawn(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Respawn — случайный генотип, стартовая энергия |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_NBE::Respawn(int i)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
bro [i].c [c] = u.SeInDiSp(u.RNDfromCI(rangeMin [c], rangeMax [c]),
|
||||
rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
bro [i].f = -DBL_MAX;
|
||||
bro [i].E = E0;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Gauss — стандартное нормальное (Box–Muller) |
|
||||
//+------------------------------------------------------------------+
|
||||
double C_AO_NBE::Gauss()
|
||||
{
|
||||
double u1 = u.RNDfromCI(0.0, 1.0);
|
||||
double u2 = u.RNDfromCI(0.0, 1.0);
|
||||
if(u1 < 1e-15)
|
||||
u1 = 1e-15;
|
||||
return MathSqrt(-2.0 * MathLog(u1)) * MathCos(2.0 * M_PI * u2);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| StepNow — масштаб движения с линейным отжигом |
|
||||
//+------------------------------------------------------------------+
|
||||
double C_AO_NBE::StepNow()
|
||||
{
|
||||
double t = (double)epochNow / (double)epochsDen;
|
||||
if(t > 1.0)
|
||||
t = 1.0;
|
||||
return stepSize * (STEP_MIN_RATIO + (1.0 - STEP_MIN_RATIO) * (1.0 - t));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| RouletteByE — индекс из pool[0..n-1], взвешенный по энергии, |
|
||||
//| с исключением exclude (или -1) |
|
||||
//+------------------------------------------------------------------+
|
||||
int C_AO_NBE::RouletteByE(int &pool [], int n, int exclude)
|
||||
{
|
||||
double sum = 0.0;
|
||||
for(int k = 0; k < n; k++)
|
||||
{
|
||||
int idx = pool [k];
|
||||
if(idx == exclude)
|
||||
continue;
|
||||
double e = bro [idx].E;
|
||||
if(e < 1e-12)
|
||||
e = 1e-12;
|
||||
sum += e;
|
||||
}
|
||||
|
||||
if(sum <= 0.0)
|
||||
{
|
||||
int idx = pool [u.RNDminusOne(n)];
|
||||
return idx;
|
||||
}
|
||||
|
||||
double r = u.RNDprobab() * sum;
|
||||
double acc = 0.0;
|
||||
for(int k = 0; k < n; k++)
|
||||
{
|
||||
int idx = pool [k];
|
||||
if(idx == exclude)
|
||||
continue;
|
||||
double e = bro [idx].E;
|
||||
if(e < 1e-12)
|
||||
e = 1e-12;
|
||||
acc += e;
|
||||
if(acc >= r)
|
||||
return idx;
|
||||
}
|
||||
return pool [n - 1];
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Moving |
|
||||
//| Каждый бактероид этой эпохой делает ЛИБО плазмидный перенос, |
|
||||
//| ЛИБО хемотаксис-движение. Кандидат пишется в a[i].c. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_NBE::Moving()
|
||||
{
|
||||
//--- первый прогон: генотипы -> слоты для первичной оценки
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = bro [i].c [c];
|
||||
return;
|
||||
}
|
||||
|
||||
epochNow++;
|
||||
double step = StepNow();
|
||||
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
//--- стартуем кандидата с текущего генотипа
|
||||
for(int c = 0; c < coords; c++)
|
||||
a [i].c [c] = bro [i].c [c];
|
||||
|
||||
if(popSize > 1 && u.RNDprobab() < pPlasmid)
|
||||
{
|
||||
//--- ПЛАЗМИДНЫЙ ПЕРЕНОС: блок от донора (рулетка по энергии)
|
||||
actType [i] = 1;
|
||||
|
||||
int donor = RouletteByE(allIdx, popSize, i);
|
||||
int span = coords - transLen + 1;
|
||||
if(span < 1)
|
||||
span = 1;
|
||||
int start = u.RNDminusOne(span);
|
||||
|
||||
for(int t = 0; t < transLen; t++)
|
||||
{
|
||||
int c = start + t;
|
||||
if(c < coords)
|
||||
a [i].c [c] = bro [donor].c [c];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- ХЕМОТАКСИС: покоординатное гауссово движение
|
||||
actType [i] = 0;
|
||||
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double rng = rangeMax [c] - rangeMin [c];
|
||||
double v = bro [i].c [c] + Gauss() * step * rng;
|
||||
a [i].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Revision |
|
||||
//| Приёмка хода -> энергобаланс -> гибель -> деление. |
|
||||
//+------------------------------------------------------------------+
|
||||
void C_AO_NBE::Revision()
|
||||
{
|
||||
//--- глобальный лучший
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(a [i].f > fB)
|
||||
{
|
||||
fB = a [i].f;
|
||||
ArrayCopy(cB, a [i].c, 0, 0, coords);
|
||||
}
|
||||
}
|
||||
|
||||
//--- первичная фиксация
|
||||
if(!revision)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
bro [i].f = a [i].f;
|
||||
bro [i].E = E0;
|
||||
}
|
||||
revision = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//--- приёмка хода: перенос безусловно, движение — greedy
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(actType [i] == 1)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
bro [i].c [c] = a [i].c [c];
|
||||
bro [i].f = a [i].f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(a [i].f >= bro [i].f)
|
||||
{
|
||||
for(int c = 0; c < coords; c++)
|
||||
bro [i].c [c] = a [i].c [c];
|
||||
bro [i].f = a [i].f;
|
||||
}
|
||||
//--- иначе откат: bro[i] остаётся прежним
|
||||
}
|
||||
}
|
||||
|
||||
//--- энергобаланс: приход ~ популяционно-относительной адаптированности
|
||||
double fmin = DBL_MAX;
|
||||
double fmax = -DBL_MAX;
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(bro [i].f < fmin)
|
||||
fmin = bro [i].f;
|
||||
if(bro [i].f > fmax)
|
||||
fmax = bro [i].f;
|
||||
}
|
||||
double span = fmax - fmin;
|
||||
if(span < 1e-12)
|
||||
span = 1e-12;
|
||||
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
double gain = (bro [i].f - fmin) / span; // [0,1]
|
||||
bro [i].E += gain - cost;
|
||||
if(bro [i].E > Emax)
|
||||
bro [i].E = Emax;
|
||||
}
|
||||
|
||||
//--- гибель: энергетическая (E<=0) или средовая (pDeath)
|
||||
int nLiving = 0;
|
||||
bool dead [];
|
||||
ArrayResize(dead, popSize);
|
||||
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
bool die = (bro [i].E <= 0.0) || (u.RNDprobab() < pDeath);
|
||||
dead [i] = die;
|
||||
if(!die)
|
||||
{
|
||||
living [nLiving] = i;
|
||||
nLiving++;
|
||||
}
|
||||
}
|
||||
|
||||
//--- заполнение освободившихся слотов делением (или массовый респаун)
|
||||
if(nLiving == 0)
|
||||
{
|
||||
for(int i = 0; i < popSize; i++)
|
||||
Respawn(i);
|
||||
return;
|
||||
}
|
||||
|
||||
double step = StepNow();
|
||||
|
||||
for(int i = 0; i < popSize; i++)
|
||||
{
|
||||
if(!dead [i])
|
||||
continue;
|
||||
|
||||
//--- родитель — энергичный живой (рулетка по энергии)
|
||||
int p = RouletteByE(living, nLiving, -1);
|
||||
|
||||
//--- деление: потомок = мутированная копия родителя рядом
|
||||
for(int c = 0; c < coords; c++)
|
||||
{
|
||||
double rng = rangeMax [c] - rangeMin [c];
|
||||
double v = bro [p].c [c] + Gauss() * step * rng;
|
||||
bro [i].c [c] = u.SeInDiSp(v, rangeMin [c], rangeMax [c], rangeStep [c]);
|
||||
}
|
||||
|
||||
//--- энергия делится пополам
|
||||
double half = bro [p].E * 0.5;
|
||||
bro [i].E = half;
|
||||
bro [p].E = bro [p].E - half;
|
||||
|
||||
//--- фитнес потомка оценится на следующей эпохе; оценка-заглушка
|
||||
bro [i].f = bro [p].f;
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -247,7 +247,8 @@ class C_TSEA_clusters
|
||||
{
|
||||
if (arr [j].distance > arr [j + 1].distance)
|
||||
{
|
||||
DistanceIndex temp = arr [j];
|
||||
DistanceIndex temp;
|
||||
temp = arr [j];
|
||||
arr [j] = arr [j + 1];
|
||||
arr [j + 1] = temp;
|
||||
}
|
||||
@@ -313,7 +314,7 @@ class C_AO_TSEA : public C_AO
|
||||
C_AO_TSEA ()
|
||||
{
|
||||
ao_name = "TSEA";
|
||||
ao_desc = "Turtle Shell Evolution Algorithm";
|
||||
ao_desc = "Turtle Shell Evolution Algorithm (joo)";
|
||||
ao_link = "https://www.mql5.com/ru/articles/14789";
|
||||
|
||||
popSize = 100; //population size
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -39,7 +39,7 @@
|
||||
position: fixed;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.5);
|
||||
z-index: 9999;
|
||||
z-index: -1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -51,41 +51,112 @@
|
||||
<th>Full Name</th>
|
||||
</tr>
|
||||
<tr><td>ANS</td><td><a href="https://www.mql5.com/ru/articles/15049" target="_blank">across neighbourhood search</a></td></tr>
|
||||
<tr><td>CLA</td><td><a href="https://www.mql5.com/ru/articles/14878" target="_blank">code lock algorithm</a></td></tr>
|
||||
<tr><td>CLA</td><td><a href="https://www.mql5.com/ru/articles/14878" target="_blank">code lock algorithm (joo)</a></td></tr>
|
||||
<tr><td>AMOm</td><td><a href="https://www.mql5.com/ru/articles/15543" target="_blank">animal migration optimization M</a></td></tr>
|
||||
<tr><td>(P+O)ES</td><td><a href="https://www.mql5.com/ru/articles/13923" target="_blank">(P+O) evolution strategies</a></td></tr>
|
||||
<tr><td>CTA</td><td><a href="https://www.mql5.com/ru/articles/14841" target="_blank">comet tail algorithm</a></td></tr>
|
||||
<tr><td>CTA</td><td><a href="https://www.mql5.com/ru/articles/14841" target="_blank">comet tail algorithm (joo)</a></td></tr>
|
||||
<tr><td>TETA</td><td><a href="https://www.mql5.com/ru/articles/16963" target="_blank">time evolution travel algorithm (joo)</a></td></tr>
|
||||
<tr><td>SDSm</td><td><a href="https://www.mql5.com/ru/articles/13540" target="_blank">stochastic diffusion search M</a></td></tr>
|
||||
<tr><td>COA(Coyote)</td><td><a href="https://www.mql5.com/ru/articles/23053" target="_blank">coyote optimization algorithm</a></td></tr>
|
||||
<tr><td>ECBO</td><td><a href="https://www.mql5.com/ru/articles/21147" target="_blank">enhanced colliding bodies optimization</a></td></tr>
|
||||
<tr><td>BOAm</td><td><a href="https://www.mql5.com/ru/articles/17325" target="_blank">billiards optimization algorithm M</a></td></tr>
|
||||
<tr><td>AAm</td><td><a href="https://www.mql5.com/ru/articles/15782" target="_blank">archery algorithm M</a></td></tr>
|
||||
<tr><td>ESG</td><td><a href="https://www.mql5.com/ru/articles/14136" target="_blank">evolution of social groups</a></td></tr>
|
||||
<tr><td>SIA</td><td><a href="https://www.mql5.com/ru/articles/13870" target="_blank">simulated isotropic annealing</a></td></tr>
|
||||
<tr><td>ESG</td><td><a href="https://www.mql5.com/ru/articles/14136" target="_blank">evolution of social groups (joo)</a></td></tr>
|
||||
<tr><td>SIA</td><td><a href="https://www.mql5.com/ru/articles/13870" target="_blank">simulated isotropic annealing (joo)</a></td></tr>
|
||||
<tr><td>ACA</td><td><a href="https://www.mql5.com/ru/articles/22525" target="_blank">andean condor algorithm</a></td></tr>
|
||||
<tr><td>EOm</td><td><a href="https://www.mql5.com/ru/articles/18755" target="_blank">extremal optimization M</a></td></tr>
|
||||
<tr><td>BBO</td><td><a href="https://www.mql5.com/ru/articles/18354" target="_blank">biogeography-based optimization</a></td></tr>
|
||||
<tr><td>ACS</td><td><a href="https://www.mql5.com/ru/articles/15004" target="_blank">artificial cooperative search</a></td></tr>
|
||||
<tr><td>DA</td><td><a href="https://www.mql5.com/ru/articles/16999" target="_blank">dialectical algorithm</a></td></tr>
|
||||
<tr><td>BHAm</td><td><a href="https://www.mql5.com/ru/articles/16655" target="_blank">black hole algorithm M</a></td></tr>
|
||||
<tr><td>ASO</td><td><a href="https://www.mql5.com/ru/articles/15511" target="_blank">anarchy society optimization</a></td></tr>
|
||||
<tr><td>TSEA</td><td><a href="https://www.mql5.com/ru/articles/14789" target="_blank">turtle shell evolution algorithm</a></td></tr>
|
||||
<tr><td>RFO</td><td><a href="https://www.mql5.com/ru/articles/17063" target="_blank">royal flush optimization (joo)</a></td></tr>
|
||||
<tr><td>AOSm</td><td><a href="https://www.mql5.com/ru/articles/16315" target="_blank">atomic orbital search M</a></td></tr>
|
||||
<tr><td>TSEA</td><td><a href="https://www.mql5.com/ru/articles/14789" target="_blank">turtle shell evolution algorithm (joo)</a></td></tr>
|
||||
<tr><td>BSA</td><td><a href="https://www.mql5.com/ru/articles/18568" target="_blank">backtracking search algorithm</a></td></tr>
|
||||
<tr><td>DE</td><td><a href="https://www.mql5.com/ru/articles/13781" target="_blank">differential evolution</a></td></tr>
|
||||
<tr><td>SRA</td><td><a href="https://www.mql5.com/ru/articles/17380" target="_blank">successful restaurateur algorithm (joo)</a></td></tr>
|
||||
<tr><td>BO</td><td><a href="https://www.mql5.com/ru/articles/20245" target="_blank">bonobo optimizer</a></td></tr>
|
||||
<tr><td>CRO</td><td><a href="https://www.mql5.com/ru/articles/15080" target="_blank">chemical reaction optimisation</a></td></tr>
|
||||
<tr><td>CSO</td><td><a href="https://www.mql5.com/ru/articles/21727" target="_blank">competitive swarm optimizer</a></td></tr>
|
||||
<tr><td>BIO</td><td><a href="https://www.mql5.com/ru/articles/17246" target="_blank">blood inheritance optimization (joo)</a></td></tr>
|
||||
<tr><td>DOA</td><td><a href="https://www.mql5.com/ru/articles/19177" target="_blank">dream optimization algorithm</a></td></tr>
|
||||
<tr><td>BSA</td><td><a href="https://www.mql5.com/ru/articles/14491" target="_blank">bird swarm algorithm</a></td></tr>
|
||||
<tr><td>BEA</td><td><a href="https://www.mql5.com/ru/articles/23232" target="_blank">bacterial evolutionary algorithm</a></td></tr>
|
||||
<tr><td>BWOm</td><td><a href="https://www.mql5.com/ru/articles/22686" target="_blank">beluga whale optimization M</a></td></tr>
|
||||
<tr><td>DEA</td><td><a href="https://www.mql5.com/ru/articles/18495" target="_blank">dolphin echolocation algorithm</a></td></tr>
|
||||
<tr><td>HS</td><td><a href="https://www.mql5.com/ru/articles/12163" target="_blank">harmony search</a></td></tr>
|
||||
<tr><td>SSG</td><td><a href="https://www.mql5.com/ru/articles/12268" target="_blank">saplings sowing and growing</a></td></tr>
|
||||
<tr><td>BCOm</td><td><a href="https://www.mql5.com/ru/articles/15711" target="_blank">bacterial chemotaxis optimization M</a></td></tr>
|
||||
<tr><td>ABO</td><td><a href="https://www.mql5.com/ru/articles/16024" target="_blank">african buffalo optimization</a></td></tr>
|
||||
<tr><td>(PO)ES</td><td><a href="https://www.mql5.com/ru/articles/13923" target="_blank">(PO) evolution strategies</a></td></tr>
|
||||
<tr><td>FBA</td><td><a href="https://www.mql5.com/ru/articles/17458" target="_blank">fractal-based algorithm</a></td></tr>
|
||||
<tr><td>TSm</td><td><a href="https://www.mql5.com/ru/articles/15654" target="_blank">tabu search M</a></td></tr>
|
||||
<tr><td>BSO</td><td><a href="https://www.mql5.com/ru/articles/14707" target="_blank">brain storm optimization</a></td></tr>
|
||||
<tr><td>WOAm</td><td><a href="https://www.mql5.com/ru/articles/14414" target="_blank">wale optimization algorithm M</a></td></tr>
|
||||
<tr><td>AEFA</td><td><a href="https://www.mql5.com/ru/articles/15162" target="_blank">artificial electric field algorithm</a></td></tr>
|
||||
<tr><td>AEO</td><td><a href="https://www.mql5.com/ru/articles/16058" target="_blank">artificial ecosystem-based optimization algorithm</a></td></tr>
|
||||
<tr><td>CAm</td><td><a href="https://www.mql5.com/ru/articles/18057" target="_blank">camel algorithm M</a></td></tr>
|
||||
<tr><td>ACOm</td><td><a href="https://www.mql5.com/ru/articles/11602" target="_blank">ant colony optimization M</a></td></tr>
|
||||
<tr><td>CMAES</td><td><a href="https://www.mql5.com/ru/articles/18227" target="_blank">covariance matrix adaptation evolution strategy</a></td></tr>
|
||||
<tr><td>DA(Duelist)</td><td><a href="https://www.mql5.com/ru/articles/19093" target="_blank">duelist algorithm</a></td></tr>
|
||||
<tr><td>ECOi</td><td><a href="https://www.mql5.com/ru/articles/20608" target="_blank">eco-inspired evolutionary algorithm</a></td></tr>
|
||||
<tr><td>BFO-GA</td><td><a href="https://www.mql5.com/ru/articles/14011" target="_blank">bacterial foraging optimization - genetic algorithm</a></td></tr>
|
||||
<tr><td>BOA(Bull)</td><td><a href="https://www.mql5.com/ru/articles/22390" target="_blank">bull optimization algorithm</a></td></tr>
|
||||
<tr><td>SOA</td><td><a href="https://www.mql5.com/ru/articles/16364#tag3" target="_blank">simple optimization algorithm</a></td></tr>
|
||||
<tr><td>ABHA</td><td><a href="https://www.mql5.com/ru/articles/15347" target="_blank">artificial bee hive algorithm</a></td></tr>
|
||||
<tr><td>DO</td><td><a href="https://www.mql5.com/ru/articles/20540" target="_blank">dandelion optimizer</a></td></tr>
|
||||
<tr><td>CLA_l</td><td><a href="https://www.mql5.com/ru/articles/18857" target="_blank">competitive learning algorithm</a></td></tr>
|
||||
<tr><td>CSA(Crow)</td><td><a href="https://www.mql5.com/ru/articles/19669" target="_blank">crow search algorithm</a></td></tr>
|
||||
<tr><td>ACMO</td><td><a href="https://www.mql5.com/ru/articles/15921" target="_blank">atmospheric cloud model optimization</a></td></tr>
|
||||
<tr><td>ADAMm</td><td><a href="https://www.mql5.com/ru/articles/16443" target="_blank">adaptive moment estimation M</a></td></tr>
|
||||
<tr><td>NBE</td><td><a href="https://www.mql5.com/ru/articles/23267" target="_blank">numaoka bacterial evolution</a></td></tr>
|
||||
<tr><td>CryStAlm</td><td><a href="https://www.mql5.com/ru/articles/19899" target="_blank">crystal structure algorithm M</a></td></tr>
|
||||
<tr><td>BOA</td><td><a href="https://www.mql5.com/ru/articles/21209" target="_blank">butterfly optimization algorithm</a></td></tr>
|
||||
<tr><td>CoSO</td><td><a href="https://www.mql5.com/ru/articles/18886" target="_blank">community of scientist optimization</a></td></tr>
|
||||
<tr><td>CGO</td><td><a href="https://www.mql5.com/ru/articles/17047" target="_blank">chaos game optimization</a></td></tr>
|
||||
<tr><td>BSO(Beetle)</td><td><a href="https://www.mql5.com/ru/articles/21292" target="_blank">beetle swarm optimization</a></td></tr>
|
||||
<tr><td>ATAm</td><td><a href="https://www.mql5.com/ru/articles/16588" target="_blank">artificial tribe algorithm M</a></td></tr>
|
||||
<tr><td>A3</td><td><a href="https://www.mql5.com/ru/articles/18958" target="_blank">artificial atom algorithm</a></td></tr>
|
||||
<tr><td>ECOc</td><td><a href="https://www.mql5.com/ru/articles/20611" target="_blank">ecological cycle optimizer</a></td></tr>
|
||||
<tr><td>CROm</td><td><a href="https://www.mql5.com/ru/articles/17760" target="_blank">coral reef optimization M</a></td></tr>
|
||||
<tr><td>dDCA</td><td><a href="https://www.mql5.com/ru/articles/20430" target="_blank">deterministic dendritic cell algorithm</a></td></tr>
|
||||
<tr><td>CFO</td><td><a href="https://www.mql5.com/ru/articles/17167" target="_blank">central force optimization</a></td></tr>
|
||||
<tr><td>ASHA</td><td><a href="https://www.mql5.com/ru/articles/15980" target="_blank">artificial showering algorithm</a></td></tr>
|
||||
<tr><td>ASBO</td><td><a href="https://www.mql5.com/ru/articles/15347" target="_blank">adaptive social behavior optimization</a></td></tr>
|
||||
<tr><td>DSA</td><td><a href="https://www.mql5.com/ru/articles/20346" target="_blank">differential search algorithm</a></td></tr>
|
||||
<tr><td>BIA</td><td><a href="https://www.mql5.com/ru/articles/19444" target="_blank">bison algorithm</a></td></tr>
|
||||
<tr><td>AOA</td><td><a href="https://www.mql5.com/ru/articles/22648" target="_blank">archimedes optimization algorithm</a></td></tr>
|
||||
<tr><td>DCA</td><td><a href="https://www.mql5.com/ru/articles/20479" target="_blank">dendritic cell algorithm</a></td></tr>
|
||||
<tr><td>ES</td><td><a href="https://www.mql5.com/ru/articles/18460" target="_blank">eagle strategy</a></td></tr>
|
||||
<tr><td>BRO</td><td><a href="https://www.mql5.com/ru/articles/17688" target="_blank">battle royale optimizer</a></td></tr>
|
||||
<tr><td>MEC</td><td><a href="https://www.mql5.com/ru/articles/13432" target="_blank">mind evolutionary computation</a></td></tr>
|
||||
<tr><td>EOSA</td><td><a href="https://www.mql5.com/ru/articles/20932" target="_blank">ebola optimization search algorithm</a></td></tr>
|
||||
<tr><td>FBL</td><td><a href="https://www.mql5.com/ru/articles/21821" target="_blank">flock by leader</a></td></tr>
|
||||
<tr><td>CSA</td><td><a href="https://www.mql5.com/ru/articles/17143" target="_blank">circle search algorithm</a></td></tr>
|
||||
<tr><td>IWO</td><td><a href="https://www.mql5.com/ru/articles/11990" target="_blank">invasive weed optimization</a></td></tr>
|
||||
<tr><td>BUZOA</td><td><a href="https://www.mql5.com/ru/articles/21843" target="_blank">buzzard optimization algorithm</a></td></tr>
|
||||
<tr><td>Micro-AIS</td><td><a href="https://www.mql5.com/ru/articles/13951" target="_blank">micro artificial immune system</a></td></tr>
|
||||
<tr><td>DOS</td><td><a href="https://www.mql5.com/ru/articles/18154" target="_blank">deterministic oscillatory search</a></td></tr>
|
||||
<tr><td>EMA</td><td><a href="https://www.mql5.com/ru/articles/18605" target="_blank">exchange market algorithm</a></td></tr>
|
||||
<tr><td>COAm</td><td><a href="https://www.mql5.com/ru/articles/11786" target="_blank">cuckoo optimization algorithm M</a></td></tr>
|
||||
<tr><td>ECEA</td><td><a href="https://www.mql5.com/ru/articles/20052" target="_blank">elite crystal evolution algorithm</a></td></tr>
|
||||
<tr><td>SDOm</td><td><a href="https://www.mql5.com/ru/articles/12252" target="_blank">spiral dynamics optimization M</a></td></tr>
|
||||
<tr><td>DA(Dragonfly)</td><td><a href="https://www.mql5.com/ru/articles/21310" target="_blank">dragonfly algorithm</a></td></tr>
|
||||
<tr><td>NMm</td><td><a href="https://www.mql5.com/ru/articles/13805" target="_blank">Nelder-Mead method M</a></td></tr>
|
||||
<tr><td>DOA</td><td><a href="https://www.mql5.com/ru/articles/19458" target="_blank">dingo optimization algorithm</a></td></tr>
|
||||
<tr><td>COA(CHAOS)</td><td><a href="https://www.mql5.com/ru/articles/16729" target="_blank">Chaos Optimization Algorithm</a></td></tr>
|
||||
<tr><td>BM</td><td><a href="https://www.mql5.com/ru/articles/19757" target="_blank">blue monkey algorithm</a></td></tr>
|
||||
<tr><td>BBBC</td><td><a href="https://www.mql5.com/ru/articles/16701" target="_blank">big bang - big crunch algorithm</a></td></tr>
|
||||
<tr><td>CPA</td><td><a href="https://www.mql5.com/ru/articles/16877" target="_blank">cyclic parthenogenesis algorithm</a></td></tr>
|
||||
<tr><td>CA_Cricket</td><td><a href="https://www.mql5.com/ru/articles/21058" target="_blank">cricket algorithm</a></td></tr>
|
||||
<tr><td>BChimp</td><td><a href="https://www.mql5.com/ru/articles/23132" target="_blank">Chimp Optimization Algorithm</a></td></tr>
|
||||
<tr><td>FAm</td><td><a href="https://www.mql5.com/ru/articles/11873" target="_blank">firefly algorithm M</a></td></tr>
|
||||
<tr><td>ASSA</td><td><a href="https://www.mql5.com/ru/articles/21671" target="_blank">artificial searching swarm algorithm</a></td></tr>
|
||||
<tr><td>CHA</td><td><a href="https://www.mql5.com/ru/articles/18132" target="_blank">color harmony algorithm</a></td></tr>
|
||||
<tr><td>GSA</td><td><a href="https://www.mql5.com/ru/articles/12072" target="_blank">gravitational search algorithm</a></td></tr>
|
||||
<tr><td>CVO</td><td><a href="https://www.mql5.com/ru/articles/22887" target="_blank">corona virus optimization</a></td></tr>
|
||||
<tr><td>ACCS</td><td><a href="https://www.mql5.com/ru/articles/19861" target="_blank">artificial coronary circulation system</a></td></tr>
|
||||
<tr><td>BFO</td><td><a href="https://www.mql5.com/ru/articles/12031" target="_blank">bacterial foraging optimization</a></td></tr>
|
||||
<tr><td>ABC</td><td><a href="https://www.mql5.com/ru/articles/11736" target="_blank">artificial bee colony</a></td></tr>
|
||||
<tr><td>BA</td><td><a href="https://www.mql5.com/ru/articles/11915" target="_blank">bat algorithm</a></td></tr>
|
||||
@@ -99,8 +170,11 @@
|
||||
<tr><td>FSS</td><td><a href="https://www.mql5.com/ru/articles/11841" target="_blank">fish school search</a></td></tr>
|
||||
<tr><td>RND</td><td><a href="https://www.mql5.com/ru/articles/8122" target="_blank">random</a></td></tr>
|
||||
<tr><td>GWO</td><td><a href="https://www.mql5.com/ru/articles/11785" target="_blank">grey wolf optimizer</a></td></tr>
|
||||
<tr><td>AOA</td><td><a href="https://www.mql5.com/ru/articles/16364" target="_blank">arithmetic optimization algorithm</a></td></tr>
|
||||
<tr><td>CSS</td><td><a href="https://www.mql5.com/ru/articles/13662" target="_blank">charged system search</a></td></tr>
|
||||
<tr><td>EM</td><td><a href="https://www.mql5.com/ru/articles/12352" target="_blank">electroMagnetism-like algorithm</a></td></tr>
|
||||
<tr><td>DOAm</td><td><a href="https://www.mql5.com/ru/articles/19187" target="_blank">dingo optimization algorithm M</a></td></tr>
|
||||
<tr><td>HHO</td><td><a href="https://www.mql5.com/ru/articles/21898" target="_blank">harris hawks optimization</a></td></tr>
|
||||
</table>
|
||||
|
||||
<script>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,262 @@
|
||||
//+----------------------------------------------------------------------------+
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//+----------------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2007-2026, JQS aka Joo."
|
||||
#property link "https://www.mql5.com/ru/users/joo"
|
||||
#property version "1.00"
|
||||
#property script_show_inputs
|
||||
|
||||
#include <Math\AOs\TestFunctions.mqh>
|
||||
#include <Math\AOs\TestStandFunctions.mqh>
|
||||
#include <Math\AOs\TestStand3D.mqh>
|
||||
#include <Math\AOs\PopulationAO\#C_AO.mqh>
|
||||
#include <Math\AOs\PopulationAO\#C_AO_enum.mqh>
|
||||
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
input string AOparam = "----------------"; //AO parameters-----------
|
||||
input E_AO AOexactly_P = NONE_AO;
|
||||
|
||||
input string TestStand_1 = "----------------"; //Test stand--------------
|
||||
input double ArgumentStep_P = 0.0; //Argument Step
|
||||
|
||||
input string TestStand_2 = "----------------"; //------------------------
|
||||
input int Test1FuncRuns_P = 5; //Test #1: Number of functions in the test
|
||||
input int Test2FuncRuns_P = 25; //Test #2: Number of functions in the test
|
||||
input int Test3FuncRuns_P = 500; //Test #3: Number of functions in the test
|
||||
|
||||
input string TestStand_3 = "----------------"; //------------------------
|
||||
input EFunc Function1 = Hilly;
|
||||
input EFunc Function2 = Forest;
|
||||
input EFunc Function3 = Megacity;
|
||||
|
||||
input string TestStand_4 = "----------------"; //------------------------
|
||||
input int NumbTestFuncRuns_P = 10000; //Number of test function runs
|
||||
input int NumberRepetTest_P = 10; //Test repets number
|
||||
|
||||
input string TestStand_5 = "----------------"; //------------------------
|
||||
input int DelayInMS_P = 0;
|
||||
input bool Video_P = true; //Show video
|
||||
input bool Use3D_P = true; //Показывать 3D-визуализацию
|
||||
input int Grid3D_P = 80; //Разрешение 3D-сетки (10..200)
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
C_AO *AO = SelectAO(AOexactly_P);
|
||||
|
||||
if(AO == NULL)
|
||||
{
|
||||
Print("AO is not selected...");
|
||||
return;
|
||||
}
|
||||
|
||||
Print(AO.GetName(), "|", AO.GetDesc(), "|", AO.GetParams());
|
||||
|
||||
//--- 2D стенд
|
||||
C_TestStand ST;
|
||||
ST.Init(750, 375);
|
||||
|
||||
//--- 3D стенд
|
||||
C_TestStand3D *ST3 = NULL;
|
||||
if(Use3D_P)
|
||||
{
|
||||
ST3 = new C_TestStand3D();
|
||||
if(!ST3.Init("__3DView__", 5, 30, ST.H, ST.H))
|
||||
{
|
||||
Print("C_TestStand3D: Init failed — 3D-режим отключён");
|
||||
delete ST3;
|
||||
ST3 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
double allScore = 0.0;
|
||||
double allTests = 0.0;
|
||||
|
||||
C_Function *F1 = SelectFunction(Function1);
|
||||
C_Function *F2 = SelectFunction(Function2);
|
||||
C_Function *F3 = SelectFunction(Function3);
|
||||
|
||||
if(F1 != NULL)
|
||||
{
|
||||
Print("=============================");
|
||||
ST.CanvasErase();
|
||||
if(ST3 != NULL)
|
||||
{ST3.BuildSurface(*F1, Grid3D_P); ST3.Show(true); }
|
||||
|
||||
FuncTests(AO, ST, ST3, *F1, Test1FuncRuns_P, clrLime, allScore, allTests);
|
||||
FuncTests(AO, ST, ST3, *F1, Test2FuncRuns_P, clrAqua, allScore, allTests);
|
||||
FuncTests(AO, ST, ST3, *F1, Test3FuncRuns_P, clrOrangeRed, allScore, allTests);
|
||||
delete F1;
|
||||
}
|
||||
|
||||
if(F2 != NULL)
|
||||
{
|
||||
Print("=============================");
|
||||
ST.CanvasErase();
|
||||
if(ST3 != NULL)
|
||||
{ST3.BuildSurface(*F2, Grid3D_P); ST3.Show(true); }
|
||||
|
||||
FuncTests(AO, ST, ST3, *F2, Test1FuncRuns_P, clrLime, allScore, allTests);
|
||||
FuncTests(AO, ST, ST3, *F2, Test2FuncRuns_P, clrAqua, allScore, allTests);
|
||||
FuncTests(AO, ST, ST3, *F2, Test3FuncRuns_P, clrOrangeRed, allScore, allTests);
|
||||
delete F2;
|
||||
}
|
||||
|
||||
if(F3 != NULL)
|
||||
{
|
||||
Print("=============================");
|
||||
ST.CanvasErase();
|
||||
if(ST3 != NULL)
|
||||
{ST3.BuildSurface(*F3, Grid3D_P); ST3.Show(true); }
|
||||
|
||||
FuncTests(AO, ST, ST3, *F3, Test1FuncRuns_P, clrLime, allScore, allTests);
|
||||
FuncTests(AO, ST, ST3, *F3, Test2FuncRuns_P, clrAqua, allScore, allTests);
|
||||
FuncTests(AO, ST, ST3, *F3, Test3FuncRuns_P, clrOrangeRed, allScore, allTests);
|
||||
delete F3;
|
||||
}
|
||||
|
||||
Print("=============================");
|
||||
if(allTests > 0.0)
|
||||
Print("All score: ", DoubleToString(allScore, 5), " (", DoubleToString(allScore * 100.0 / allTests, 2), "%)");
|
||||
|
||||
if(ST3 != NULL)
|
||||
{ST3.Show(false); delete ST3; }
|
||||
ST.Canvas.Destroy();
|
||||
delete AO;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void FuncTests(C_AO &ao,
|
||||
C_TestStand &st,
|
||||
C_TestStand3D *st3,
|
||||
C_Function &f,
|
||||
const int funcCount,
|
||||
const color clrConv,
|
||||
double &allScore,
|
||||
double &allTests)
|
||||
{
|
||||
if(funcCount <= 0)
|
||||
return;
|
||||
|
||||
allTests++;
|
||||
|
||||
if(Video_P)
|
||||
{
|
||||
st.DrawFunctionGraph(f);
|
||||
st.SendGraphToCanvas();
|
||||
st.MaxMinDr(f);
|
||||
st.Update();
|
||||
}
|
||||
|
||||
int xConv = 0.0;
|
||||
int yConv = 0.0;
|
||||
double aveResult = 0.0;
|
||||
int params = funcCount * 2;
|
||||
int epochCount = NumbTestFuncRuns_P / (int)ao.params [0].val;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double rangeMin [], rangeMax [], rangeStep [];
|
||||
ArrayResize(rangeMin, params);
|
||||
ArrayResize(rangeMax, params);
|
||||
ArrayResize(rangeStep, params);
|
||||
|
||||
for(int i = 0; i < funcCount; i++)
|
||||
{
|
||||
rangeMax [i * 2] = f.GetMaxRangeX();
|
||||
rangeMin [i * 2] = f.GetMinRangeX();
|
||||
rangeStep [i * 2] = ArgumentStep_P;
|
||||
|
||||
rangeMax [i * 2 + 1] = f.GetMaxRangeY();
|
||||
rangeMin [i * 2 + 1] = f.GetMinRangeY();
|
||||
rangeStep [i * 2 + 1] = ArgumentStep_P;
|
||||
}
|
||||
|
||||
double ag3D [];
|
||||
|
||||
for(int test = 0; test < NumberRepetTest_P; test++)
|
||||
{
|
||||
//--------------------------------------------------------------------------
|
||||
if(!ao.Init(rangeMin, rangeMax, rangeStep, epochCount))
|
||||
break;
|
||||
|
||||
int agCnt = ArraySize(ao.a);
|
||||
if(st3 != NULL)
|
||||
{ArrayResize(ag3D, agCnt * funcCount * 2); st3.ResetTrail(); }
|
||||
|
||||
// Optimization-------------------------------------------------------------
|
||||
for(int epochCNT = 1; epochCNT <= epochCount && !IsStopped(); epochCNT++)
|
||||
{
|
||||
if(DelayInMS_P > 0)
|
||||
Sleep(DelayInMS_P);
|
||||
Comment(epochCNT);
|
||||
|
||||
ao.Moving();
|
||||
|
||||
for(int set = 0; set < ArraySize(ao.a); set++)
|
||||
{
|
||||
ao.a [set].f = f.CalcFunc(ao.a [set].c);
|
||||
}
|
||||
|
||||
ao.Revision();
|
||||
|
||||
//--- 2D визуализация -------------------------------------------
|
||||
if(Video_P)
|
||||
{
|
||||
//drawing a population--------------------------------------------------
|
||||
st.SendGraphToCanvas();
|
||||
|
||||
for(int i = 0; i < agCnt; i++)
|
||||
{
|
||||
st.PointDr(ao.a [i].c, f, 1, 1, funcCount, false);
|
||||
}
|
||||
st.PointDr(ao.cB, f, 1, 1, funcCount, true);
|
||||
|
||||
st.MaxMinDr(f);
|
||||
|
||||
//drawing a convergence graph-------------------------------------------
|
||||
xConv = (int)st.Scale(epochCNT, 1, epochCount, st.H + 2, st.W - 3, false);
|
||||
yConv = (int)st.Scale(ao.fB, f.GetMinFunValue(), f.GetMaxFunValue(), 2, st.H - 2, true);
|
||||
st.Canvas.FillCircle(xConv, yConv, 1, COLOR2RGB(clrConv));
|
||||
|
||||
st.Update();
|
||||
}
|
||||
|
||||
//--- 3D визуализация -------------------------------------------
|
||||
if(st3 != NULL)
|
||||
{
|
||||
for(int i = 0; i < agCnt; i++)
|
||||
for(int j = 0; j < funcCount; j++)
|
||||
{
|
||||
ag3D [(i * funcCount + j) * 2] = ao.a [i].c [j * 2];
|
||||
ag3D [(i * funcCount + j) * 2 + 1] = ao.a [i].c [j * 2 + 1];
|
||||
}
|
||||
|
||||
st3.OnTimer(0.033);
|
||||
st3.SetAgents(ag3D, agCnt, funcCount, f, ao.cB);
|
||||
st3.Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
aveResult += ao.fB;
|
||||
}
|
||||
|
||||
aveResult /= (double)NumberRepetTest_P;
|
||||
|
||||
double score = aveResult;
|
||||
|
||||
Print(funcCount, " ", f.GetFuncName(), "'s; Func runs: ", NumbTestFuncRuns_P, "; result: ", aveResult);
|
||||
allScore += score;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,121 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Copyright 2007-2026, Andrey Dik |
|
||||
//| https://www.mql5.com/ru/users/joo |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2007-2026, JQS aka Joo."
|
||||
#property link "https://www.mql5.com/ru/users/joo"
|
||||
#property version "1.00"
|
||||
#property script_show_inputs
|
||||
|
||||
#include <Math\AOs\TestFunctions.mqh>
|
||||
#include <Math\AOs\PopulationAO\#C_AO.mqh>
|
||||
#include <Math\AOs\PopulationAO\#C_AO_enum.mqh>
|
||||
|
||||
//————————————————————————————————————————————————————————————————————
|
||||
input string AOparam = "----------------"; //AO parameters-----------
|
||||
input E_AO AOexactly_P = NONE_AO;
|
||||
|
||||
input string TestStand_P = "----------------"; //Test stand---------------
|
||||
input int NumbTestFuncRuns_P = 1e4; // Количество вычислений функции
|
||||
input int NumberRepetTest_P = 10; // Количество повторных прогонов
|
||||
//————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnStart()
|
||||
{
|
||||
C_AO *AO = SelectAO(AOexactly_P);
|
||||
|
||||
if(AO == NULL)
|
||||
{
|
||||
Print("AO is not selected...");
|
||||
return;
|
||||
}
|
||||
|
||||
Print(AO.GetName(), "|", AO.GetDesc(), "|", AO.GetParams());
|
||||
|
||||
//--- создаём 5 функций
|
||||
#define NFUNCS 5
|
||||
C_Function *funcs [NFUNCS];
|
||||
funcs [0] = new C_Hilly();
|
||||
funcs [1] = new C_Forest();
|
||||
funcs [2] = new C_Megacity();
|
||||
funcs [3] = new C_Peaks();
|
||||
funcs [4] = new C_Skin();
|
||||
|
||||
//--- 10 координат: пара 0-1 = Hilly, 2-3 = Forest, 4-5 = Megacity,
|
||||
// 6-7 = Peaks, 8-9 = Skin
|
||||
int params = NFUNCS * 2;
|
||||
|
||||
double rangeMin [];
|
||||
double rangeMax [];
|
||||
double rangeStep [];
|
||||
ArrayResize(rangeMin, params);
|
||||
ArrayResize(rangeMax, params);
|
||||
ArrayResize(rangeStep, params);
|
||||
|
||||
for(int i = 0; i < NFUNCS; i++)
|
||||
{
|
||||
rangeMin [i * 2] = funcs [i].GetMinRangeX();
|
||||
rangeMax [i * 2] = funcs [i].GetMaxRangeX();
|
||||
rangeStep [i * 2] = 0.0;
|
||||
|
||||
rangeMin [i * 2 + 1] = funcs [i].GetMinRangeY();
|
||||
rangeMax [i * 2 + 1] = funcs [i].GetMaxRangeY();
|
||||
rangeStep [i * 2 + 1] = 0.0;
|
||||
}
|
||||
|
||||
//--- запуск тестов
|
||||
int epochCount = NumbTestFuncRuns_P / (int)AO.params [0].val;
|
||||
double aveResult = 0.0;
|
||||
|
||||
Print("=============================");
|
||||
Print("Composite test: Hilly + Forest + Megacity + Peaks + Skin");
|
||||
Print("Coordinates: ", params, "; Epochs: ", epochCount,
|
||||
"; Repeats: ", NumberRepetTest_P);
|
||||
Print("=============================");
|
||||
|
||||
for(int test = 0; test < NumberRepetTest_P; test++)
|
||||
{
|
||||
if(!AO.Init(rangeMin, rangeMax, rangeStep, epochCount))
|
||||
break;
|
||||
|
||||
for(int epochCNT = 1; epochCNT <= epochCount && !IsStopped(); epochCNT++)
|
||||
{
|
||||
AO.Moving();
|
||||
|
||||
//--- расчёт fitness для каждого агента
|
||||
for(int set = 0; set < ArraySize(AO.a); set++)
|
||||
{
|
||||
double sum = 0.0;
|
||||
for(int i = 0; i < NFUNCS; i++)
|
||||
{
|
||||
sum += funcs [i].Core(AO.a [set].c [i * 2],
|
||||
AO.a [set].c [i * 2 + 1]);
|
||||
}
|
||||
AO.a [set].f = sum / NFUNCS;
|
||||
}
|
||||
|
||||
AO.Revision();
|
||||
}
|
||||
|
||||
Print("Run ", test + 1, "/", NumberRepetTest_P, ": ", AO.fB);
|
||||
aveResult += AO.fB;
|
||||
}
|
||||
|
||||
aveResult /= (double)NumberRepetTest_P;
|
||||
|
||||
Print("=============================");
|
||||
Print("Average result: ", DoubleToString(aveResult, 10),
|
||||
" (", DoubleToString(aveResult * 100.0, 2), "%)");
|
||||
Print("=============================");
|
||||
|
||||
//--- освобождение
|
||||
for(int i = 0; i < NFUNCS; i++)
|
||||
delete funcs [i];
|
||||
delete AO;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -1,31 +1,109 @@
|
||||
A list of implemented optimization algorithms:
|
||||
A [group](https://t.me/+vazsAAcney4zYmZi) for communication on the topic of optimization.
|
||||
|
||||
A list of implemented optimization algorithms (M - is a modified improved version, joo - is an algorithm of my development):
|
||||
|
||||
|
||||
ANS (across neighbourhood search)
|
||||
CLA (code lock algorithm)
|
||||
CLA (code lock algorithm, joo)
|
||||
AMOm (animal migration optimization M)
|
||||
P_O_ES ((P+O) evolution strategies)
|
||||
CTA (Comet Tail Algorithm)
|
||||
CTA (Comet Tail Algorithm, joo)
|
||||
TETA (time evolution travel algorithm, joo)
|
||||
SDSm (stochastic diffusion search M)
|
||||
COA(Coyote)(coyote optimization algorithm)
|
||||
ECBO (enhanced colliding bodies optimization)
|
||||
BOAm (billiards optimization algorithm M)
|
||||
AAm (archery algorithm M)
|
||||
ESG (evolution of social groups)
|
||||
SIA (simulated isotropic annealing)
|
||||
ESG (evolution of social groups, joo)
|
||||
SIA (simulated isotropic annealing, joo)
|
||||
ACA (andean condor algorithm)
|
||||
EOm (extremal optimization M)
|
||||
BBO (biogeography-based optimization)
|
||||
ACS (artificial cooperative search)
|
||||
DA (dialectical algorithm)
|
||||
BHAm (black hole algorithm M)
|
||||
ASO (anarchy society optimization)
|
||||
TSEA (turtle shell evolution algorithm)
|
||||
RFO (royal flush optimization, joo)
|
||||
AOSm (atomic orbital search M)
|
||||
TSEA (turtle shell evolution algorithm, joo)
|
||||
BSA (backtracking search algorithm)
|
||||
DE (differential evolution)
|
||||
SRA (successful restaurateur algorithm, joo)
|
||||
BO (bonobo optimizer)
|
||||
CRO (chemical reaction optimisation)
|
||||
CSO (competitive swarm optimizer)
|
||||
BIO (blood inheritance optimization, joo)
|
||||
DOA_Dream (dream optimization algorithm)
|
||||
BSA (bird swarm algorithm)
|
||||
BEA (bacterial evolutionary algorithm)
|
||||
BWOm (beluga whale optimization M)
|
||||
DEA (dolphin echolocation algorithm)
|
||||
HS (harmony search)
|
||||
BCOm (bacterial chemotaxis optimization M)
|
||||
ABO (african buffalo optimization)
|
||||
(PO)ES ((PO) evolution strategies)
|
||||
FBA (fractal-based algorithm)
|
||||
TSm (tabu search M)
|
||||
BSO (brain storm optimization)
|
||||
WOAm (wale optimization algorithm M)
|
||||
AEFA (artificial electric field algorithm)
|
||||
AEO (artificial ecosystem based optimization)
|
||||
CAm (camel algorithm M)
|
||||
CMAES (covariance matrix adaptation evolution strategy)
|
||||
DA_Duelist (duelist algorithm)
|
||||
ECOi (eco-inspired evolutionary algorithm)
|
||||
SOA (simple optimization algorithm)
|
||||
BOA(Bull) (bull optimization algorithm)
|
||||
ABHA (artificial bee hive algorithm)
|
||||
DO (dandelion optimizer)
|
||||
CLA_L (competitive learning algorithm)
|
||||
CSA(CROW) (crow search algorithm)
|
||||
ACMO (atmospheric cloud model optimization)
|
||||
ADAMm (adaptive moment estimation)
|
||||
NBE (numaoka bacterial evolution)
|
||||
CryStAlm (crystal structure algorithm M)
|
||||
BOA (butterfly optimization algorithm)
|
||||
CoSO (community of scientist optimization)
|
||||
CGO (chaos game optimization)
|
||||
BSO(Beetle) (beetle swarm optimization)
|
||||
ATAm (artificial tribe algorithm M)
|
||||
A3 (artificial atom algorithm)
|
||||
ECOc (ecological cycle optimizer)
|
||||
CROm (coral reef optimization M)
|
||||
dDCA (deterministic dendritic cell algorithm)
|
||||
CFO (central force optimization)
|
||||
ASHA (artificial showering algorithm)
|
||||
ASBO (adaptive social behavior optimization)
|
||||
DSA (differential search algorithm)
|
||||
BIA (bison algorithm)
|
||||
AOA (archimedes optimization algorithm)
|
||||
DCA (dendritic cell algorithm)
|
||||
ES (eagle strategy)
|
||||
BRO (battle royale optimizer)
|
||||
EOSA (ebola optimization search algorithm)
|
||||
FBL (flock by leader)
|
||||
CSA (circle search algorithm)
|
||||
BUZOA (buzzard optimization algorithm)
|
||||
DOS (deterministic oscillatory search)
|
||||
EMA (exchange market algorithm)
|
||||
COAm (cuckoo optimization algorithm M)
|
||||
ECEA (elite crystal evolution algorithm)
|
||||
DA_Dragonfly (dragonfly algorithm)
|
||||
COA(CHAOS) (chaos optimization algorithm)
|
||||
BM (Blue Monkey Algorithm)
|
||||
BBBC (big bang big crunch)
|
||||
CPA (cyclic parthenogenesis algorithm)
|
||||
CA_Cricket (cricket algorithm)
|
||||
BChimp (chimp optimization algorithm)
|
||||
ASSA (artificial searching swarm algorithm)
|
||||
CHA (color harmony algorithm)
|
||||
CVO (corona virus optimization)
|
||||
ACCS (Artificial Coronary Circulation System)
|
||||
AAA (artificial algae algorithm)
|
||||
Boids (boids algorithm)
|
||||
GWO (grey wolf optimizer)
|
||||
AOA (arithmetic optimization algorithm)
|
||||
BGA (binary genetic algorithm)
|
||||
RW (random walk)
|
||||
DOAm_Dingo (dingo optimization algorithm M)
|
||||
HHO (harris hawks optimization)
|
||||
Reference in New Issue
Block a user