Add BChimp

This commit is contained in:
JQSakaJoo
2026-06-21 17:59:17 +04:00
parent b2d0c0066b
commit 05e4ca47cf
4 changed files with 310 additions and 0 deletions
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·(C1G1)≠0 — |
//| смещение сносит континуальную популяцию в угол rangeMin (в |
//| бинарном домене скрыто сигмоид-трансфером). Здесь A приведён |
//| к симметричной канонической форме ChOA: A = f·(2r1), 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);
}
//+------------------------------------------------------------------+
@@ -148,6 +148,7 @@
<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>
+1
View File
@@ -92,6 +92,7 @@ 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)