Algoritmo de camello — Camel Algorithm (CA)
Contenido
Introducción
En las últimas décadas han surgido un número importante de algoritmos de optimización inspirados en fenómenos naturales y en el comportamiento animal. Estos enfoques bioinspirados han demostrado excelentes resultados en muchas tareas. En este artículo, analizaremos un nuevo algoritmo de optimización llamado Algoritmo del Camello (CA), basado en las estrategias de supervivencia y movimiento de los camellos en condiciones extremas del desierto. El algoritmo fue desarrollado y presentado en 2016 por dos científicos: Mohammed Khalid Ibrahim y Ramzy Salim Ali.
Los camellos muestran una gran capacidad de adaptación en su comportamiento, así como características fisiológicas únicas que les permiten navegar y sobrevivir eficazmente en duros entornos desérticos con recursos limitados, temperaturas extremas y paisajes cambiantes. El algoritmo CA modela aspectos clave de este comportamiento: la influencia de la temperatura, la gestión de las reservas de agua y alimentos, la resistencia y el efecto de los "oasis" (zonas de búsqueda prometedoras), además de la interacción grupal en la caravana.
Como de costumbre, analizaremos los componentes internos del algoritmo original, lo modificaremos y probaremos ambas versiones en funciones de prueba. Los resultados se incluirán en nuestra tabla de clasificación de algoritmos de optimización.
Implementación del algoritmo
Imagine una caravana de camellos emprendiendo un viaje a través de un vasto desierto. Su objetivo es encontrar oasis de agua y comida ocultos entre las interminables arenas. Precisamente este viaje inspiró a los autores a crear el algoritmo de optimización Camel Algorithm (CA).
El algoritmo simula cómo estos asombrosos animales sobreviven y hallan recursos en las duras condiciones del desierto. Cada camello del algoritmo supone una solución potencial que explora el espacio de búsqueda (el desierto) tratando de encontrar la solución óptima (el oasis más rico).
Las caravanas de camellos viajan juntas por una razón: es una estrategia de supervivencia. En el algoritmo, la población de "camellos" (soluciones potenciales) intercambia información sobre las mejores rutas encontradas, de forma muy similar a cómo los camellos reales en una caravana siguen caminos probados hacia fuentes de agua.
Elementos clave:
Temperatura (T) — factor aleatorio que influye en el comportamiento de los camellos. En el desierto, las temperaturas varían desde noches frescas a días calurosos, lo cual afecta la velocidad y la dirección de los camellos. La capacidad única de los camellos para adaptarse a temperaturas extremas (desde noches frías hasta días calurosos en el desierto) inspiró el parámetro "temperatura" en el algoritmo. Este parámetro introduce un elemento de aleatoriedad y adaptabilidad que ayuda a evitar óptimos locales, de forma similar a cómo los camellos deben adaptar su ruta a las condiciones cambiantes.
Reservas (S) — agua y alimentos, que se agotan gradualmente a lo largo del camino. Los camellos han evolucionado para sobrevivir en algunas de las condiciones más duras del planeta. Su capacidad para distribuir eficientemente los recursos (el agua y los alimentos) se refleja directamente en el algoritmo a través del parámetro “supply”, que disminuye a lo largo del “viaje” e influye en la estrategia de búsqueda. Cuanto más tiempo viaje un camello sin encontrar un oasis, menos fuerzas le quedarán. Esta característica hace que el algoritmo resulte particularmente efectivo en problemas con recursos computacionales limitados.
Resistencia (E) — energía del camello, que depende de la temperatura y de la duración del viaje. El sol abrasador agota poco a poco las fuerzas de la caravana. Los camellos son conocidos por su excepcional resistencia y su capacidad de recorrer largas distancias con recursos mínimos. En el algoritmo, el parámetro "endurance" afecta la capacidad del agente para explorar el espacio de soluciones. Disminuye gradualmente e influye en el equilibrio entre la exploración de nuevas áreas y el uso de soluciones prometedoras ya encontradas.
Efecto Oasis — cuando un camello encuentra un lugar prometedor (la mejor solución), restablece sus reservas y su resistencia, lo que le permite seguir explorando. En el algoritmo, cuando se encuentra una solución, los parámetros "supply" y "endurance" se reponen, lo que permite una exploración más exhaustiva de esa zona, al igual que un camello se detiene en un oasis para recuperarse, por lo que esta es una de las características más interesantes del algoritmo.
Paseo aleatorio — desviaciones del camino principal que ayudan a explorar nuevos territorios.
Como se muestra en la siguiente ilustración, un grupo de cinco camellos está buscando un oasis bien abastecido en el desierto. Al principio se encuentran en lugares diferentes y se mueven en direcciones distintas:
El camello 1 se dirige hacia el norte, pero debido a la alta temperatura, su velocidad disminuye y tiene que hacer más paradas.El camello 2 encuentra un pequeño oasis (óptimo local) con algunas reservas de comida y agua. A continuación informa a los demás de su descubrimiento, pero continúa buscando, pues sospecha que en algún lugar hay un oasis más grande.
El camello 3 deambula por un terreno relativamente plano, sus reservas disminuyen gradualmente pero continúa explorando nuevas direcciones.
El camello 4 entra en una zona con temperaturas extremadamente altas, lo cual reduce significativamente su resistencia. Sin embargo, un vagabundeo aleatorio le ayuda a salir de dicha zona.
El camello 5, valiéndose de la información de otros camellos y la dirección favorable del paseo aleatorio, encuentra el oasis más rico (óptimo global).

Figura 1. Ilustración del funcionamiento del algoritmo CA
Vamos a escribir el pseudocódigo para el algoritmo CA:
// Inicialización de parámetros
Inicializar:
popSize = tamaño de la población (caravana de camellos)
Tmin = temperatura mínima
Tmax = temperatura máxima
omega = factor de carga para las reservas
dyingRate = tasa de "muerte" de camellos
alfa = parámetro de visibilidad para el efecto oasis
initialSupply = reservas iniciales de agua y alimentos (normalmente 1,0)
initialEndurance = resistencia inicial (normalmente 1,0)
totalSteps = número total de pasos en la ruta
traveledSteps = 0 (valor inicial de pasos recorridos)
// Inicialización de la población inicial
Creamos una caravana de camellos inicial (múltiples soluciones):
Para cada camello i desde 1 hasta popSize:
Generamos una solución aleatoria dentro de un rango aceptable
Establecemos los valores iniciales:
temperature [i] = valor aleatorio entre Tmin y Tmax
supply [i] = reservas iniciales
endurance [i] = resistencia inicial
Calculamos la aptitud de cada camello en la caravana.
Encontramos la mejor solución actual
// Ciclo de optimización principal
De momento (pasos recorridos < pasos totales):
traveledSteps++
// Por cada camello de la caravana
Para i desde 1 hasta popSize:
// 1. Factores de actualización (temperatura, reservas, resistencia)
// Fórmula (1): Tnow = (Tmax - Tmin) * Rand(0,1) + Tmin
temperature [i] = CalculateTemperature (i)
// Fórmula (2): Snow = Spast * (1 - ω * Pasos recorridos/Total de pasos del viaje)
supply [i] = CalculateSupply (i)
// Fórmula (4): Enow = Epast * (1 - Know/Tmax) * (1 - Pasos recorridos / Pasos totales del viaje)
endurance [i] = CalculateEndurance (i)
// 2. Comprobación de la "muerte" de un camello
Si (número aleatorio < dyingRate):
Generamos una nueva solución aleatoria para el camello i
Continuamos con la siguiente iteración
// 3. Actualizamos la posición del camello
delta = número aleatorio en el rango [-1, 1] // factor de paseo aleatorio
Guardamos las antiguas coordenadas del camello
// Para cada coordenada
Para cada coordenada c:
// Calculamos los factores para la fórmula de actualización
enduranceFactor = (1.0 - endurance [i] / initialEndurance)
supplyFactor = exp(1.0 - supply [i] / initialSupply)
// Actualizamos la posición usando la fórmula (6)
new_position [c] = old_position [c] + delta * enduranceFactor * supplyFactor * (best_position [c] - old_position [c])
// Verificamos si se ha salido de los límites y ajustamos si es necesario
new_position[c] = Llevar al rango aceptable
// 4. Aplicamos el efecto oasis
Si (número aleatorio > (1.0 - alfa) Y fitness_new > fitness_old):
// Se ha encontrado oasis, restauramos reservas y resistencia.
supply [i] = reservas iniciales
endurance [i] = resistencia inicial
// Clasificamos los camellos y hallamos la mejor solución
Actualizamos la mejor solución
// Retornamos la mejor solución final
Ahora podemos empezar a escribir el código, que incluirá tanto la versión original de los autores (algunas líneas estarán comentadas) como nuestra modificación, orientada a mejorar la lógica del algoritmo. Así, comenzamos a escribir la clase "C_AO_CAm", que representará una implementación del algoritmo CAm y heredará de la clase básica "C_AO".
La clase contiene parámetros específicos del algoritmo, como el tamaño de la población, la temperatura mínima y máxima, el factor de carga, la tasa de "muerte" de los camellos y el parámetro de visibilidad. Estos parámetros se pueden configurar durante la inicialización y se ajustan cómodamente a través del array de parámetros.
El constructor de clase define las propiedades básicas del algoritmo, incluido el nombre, la descripción y el enlace a la fuente de la idea, e inicializa el array de parámetros. En el método "SetParams", estos parámetros se pueden actualizar durante la ejecución.
La clase implementa los métodos para la inicialización de las poblaciones, los pasos de movimiento de los camellos, así como su revisión, los factores de actualización y los efectos asociados a los oasis: todo lo que modela el comportamiento de los camellos en el desierto y busca soluciones óptimas. Las propiedades principales de la clase son arrays que almacenan la temperatura de cada camello, sus reservas de agua y comida, la resistencia y los contadores de pasos dados y pasos totales. Hay variables que indican los niveles iniciales de reservas y resistencia, que normalmente se inicializan al comienzo del algoritmo.
En general, esta clase implementa una versión modificada del algoritmo de optimización basado en el comportamiento de una caravana de camellos, donde la "temperatura" y la "reserva" modelan estados de búsqueda intermedios, mientras que la dinámica del movimiento y la muerte de los camellos ayudan a encontrar eficientemente una solución.
//—————————————————————————————————————————————————————————————————————————————— class C_AO_CAm : public C_AO { public: //-------------------------------------------------------------------- ~C_AO_CAm () { } C_AO_CAm () { ao_name = "CA"; ao_desc = "Camel Algorithm M"; ao_link = "https://www.mql5.com/es/articles/18057"; popSize = 50; // размер популяции (camel caravan) Tmin = 50; // минимальная температура Tmax = 100; // максимальная температура omega = 0.8; // фактор нагрузки для supply dyingRate = 0.01; // скорость "смерти" верблюдов alpha = 0.9; // параметр видимости для эффекта оазиса ArrayResize (params, 6); params [0].name = "popSize"; params [0].val = popSize; params [1].name = "Tmin"; params [1].val = Tmin; params [2].name = "Tmax"; params [2].val = Tmax; params [3].name = "omega"; params [3].val = omega; params [4].name = "dyingRate"; params [4].val = dyingRate; params [5].name = "alpha"; params [5].val = alpha; } void SetParams () { popSize = (int)params [0].val; Tmin = params [1].val; Tmax = params [2].val; omega = params [3].val; dyingRate = params [4].val; alpha = params [5].val; } bool Init (const double &rangeMinP [], // минимальные значения const double &rangeMaxP [], // максимальные значения const double &rangeStepP [], // шаг изменения const int epochsP = 0); // количество эпох void Moving (); void Revision (); //---------------------------------------------------------------------------- double Tmin; // минимальная температура double Tmax; // максимальная температура double omega; // фактор нагрузки для supply double dyingRate; // скорость "смерти" верблюдов double alpha; // параметр видимости для эффекта оазиса private: //------------------------------------------------------------------- double temperature []; // текущая температура для каждого верблюда double supply []; // текущий запас воды и пищи для каждого верблюда double endurance []; // текущая выносливость для каждого верблюда double initialSupply; // начальный запас (обычно 1.0) double initialEndurance; // начальная выносливость (обычно 1.0) int traveledSteps; // количество пройденных шагов int totalSteps; // общее количество шагов // Вспомогательные методы void InitializePopulation (); void UpdateFactors (); void UpdatePositions (); void ApplyOasisEffect (); }; //——————————————————————————————————————————————————————————————————————————————
El método "Init" se encarga de inicializar el algoritmo CAm. Durante la ejecución de este método, se preparan las estructuras de datos y los parámetros necesarios para el trabajo posterior. Los pasos principales del método incluyen la llamada a la inicialización estándar, que establece los rangos y los pasos para cambiar las variables de búsqueda. Si la inicialización falla, el método también lo hará.
A continuación, se asigna memoria para los arrays que almacenan los parámetros de cada camello (temperatura, reservas de agua y comida, resistencia), cuyo tamaño es igual al tamaño de la población. Estas arrays son necesarios para modelar el comportamiento de los camellos durante la optimización. Luego se establecen los valores iniciales de las reservas y la resistencia y se establece en cero el número de pasos dados, así como el número total de pasos correspondiente al número de épocas.
//—————————————————————————————————————————————————————————————————————————————— bool C_AO_CAm::Init (const double &rangeMinP [], // минимальные значения const double &rangeMaxP [], // максимальные значения const double &rangeStepP [], // шаг изменения const int epochsP = 0) // количество эпох { if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; //---------------------------------------------------------------------------- // Инициализация массивов для каждого верблюда ArrayResize (temperature, popSize); ArrayResize (supply, popSize); ArrayResize (endurance, popSize); // Установка начальных значений initialSupply = 1.0; initialEndurance = 1.0; traveledSteps = 0; totalSteps = epochsP; return true; } //——————————————————————————————————————————————————————————————————————————————
El método “Moving” implementa el proceso iterativo del algoritmo encargado de actualizar los estados y los movimientos de los camellos. En primer lugar, verifica si se ha completado la primera iteración; si no, inicializa la población inicial de camellos y marca la inicialización como completada.
En cada paso subsiguiente, el contador de pasos completados aumenta, tras lo cual se realizan secuencialmente las siguientes acciones:
- La actualización de factores como la temperatura, las reservas de recursos y la resistencia de cada camello es importante para modelar el comportamiento dinámico y la búsqueda.
- La actualización de las posiciones de los camellos en el espacio de búsqueda, es decir, el desplazamiento en una dirección que potencialmente mejorará la solución.
- El uso del efecto oasis, donde los camellos pueden aumentar sus reservas y recuperar su resistencia, ayuda a evitar mínimos locales y fomenta una exploración más compleja del espacio.
Al final de cada paso, se guarda el valor de la función de aptitud de cada camello para poder comparar el estado actual con el anterior y, según esto, tomar decisiones adicionales.
//+----------------------------------------------------------------------------+ //| Основной метод оптимизации | //+----------------------------------------------------------------------------+ void C_AO_CAm::Moving () { // Первая итерация - инициализация начальной популяции if (!revision) { InitializePopulation (); revision = true; return; } // Увеличиваем счетчик пройденных шагов traveledSteps++; // Основной процесс оптимизации // 1. Обновляем факторы (температура, запас, выносливость) UpdateFactors (); // 2. Обновляем позиции верблюдов UpdatePositions (); // 3. Применяем эффект оазиса (обновление запасов и выносливости) ApplyOasisEffect (); // 4. Сохраняем состояние верблюдов for (int i = 0; i < popSize; i++) a [i].fP = a [i].f; } //——————————————————————————————————————————————————————————————————————————————
El método “Revision” se encarga de actualizar la mejor solución encontrada en la población actual de camellos. Itera todos los camellos de la población y compara el valor de la función objetivo (aptitud) de cada camello con el mejor valor actual. Si el valor de aptitud actual del camello (a[i].f) es mejor que el mejor valor actual (fB), entonces se realiza una actualización:
- A "fB" se le asigna un nuevo mejor valor (a[i].f).
- La posición (coordenadas, parámetros) del camello que ha alcanzado el mejor valor se copia desde las coordenadas del mejor camello actual (a[i].c) al array de coordenadas de la mejor solución (cB).
Después de completar el ciclo por todos los camellos de la población, "fB" y "cB" contendrán el valor y las coordenadas de la mejor solución encontrada en la iteración actual.
//+----------------------------------------------------------------------------+ //| Обновление лучшего решения | //+----------------------------------------------------------------------------+ void C_AO_CAm::Revision () { // Поиск лучшего решения в текущей популяции for (int i = 0; i < popSize; i++) { // Обновление лучшего решения if (a [i].f > fB) { fB = a [i].f; ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY); } } } //——————————————————————————————————————————————————————————————————————————————
El método "InitializePopulation" se usa para formar la población inicial de camellos en el algoritmo de optimización. Crea una distribución uniforme de soluciones iniciales en todo el espacio de búsqueda factible.
Los pasos básicos del método implican iterar toda la población, es decir, todos los camellos. Para cada camello, se generan coordenadas aleatorias dentro de los rangos permitidos para cada variable (cada coordenada). Estas coordenadas se eligen aleatoriamente para abarcar todo el rango válido de manera uniforme.
Tras generar las coordenadas, cada una de ellas se redondea al paso aceptable más cercano, lo que garantiza que la búsqueda cumpla con las restricciones de discreción. Esto se hace para garantizar que las soluciones iniciales coincidan exactamente con los rangos y pasos aceptables. Además, a cada camello se le asignan valores iniciales para parámetros como la capacidad de agua y la resistencia determinados por valores predeterminados preestablecidos para toda la población.
Como resultado de la ejecución del método, se crea una población inicial de soluciones distribuida uniformemente en todo el espacio de búsqueda, lo que facilita la organización eficiente del inicio del proceso de optimización.
//+----------------------------------------------------------------------------+ //| Инициализация начальной популяции | //+----------------------------------------------------------------------------+ void C_AO_CAm::InitializePopulation () { // Инициализация начальной популяции равномерно по всему пространству for (int i = 0; i < popSize; i++) { for (int c = 0; c < coords; c++) { // Генерация случайных координат в допустимых пределах a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); // Округление до ближайшего допустимого шага a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } // Инициализация факторов для каждого верблюда supply [i] = initialSupply; endurance [i] = initialEndurance; } } //——————————————————————————————————————————————————————————————————————————————
El método "UpdateFactors" de la clase "C_AO_CAm" se encarga de actualizar los factores clave que influyen en el comportamiento de cada "camello" de la población: las temperatura, las reservas y la resistencia. Estos factores cambian dinámicamente en cada iteración del algoritmo e influyen en el proceso de búsqueda de la solución óptima.
En primer lugar, se calcula “journeyRatio”, que es la relación entre el número de pasos recorridos “traveledSteps” y el número total de pasos “totalSteps”. Este valor muestra el progreso de la ejecución del algoritmo. Para cada camello (i desde 0 hasta popSize -1) la temperatura (temperatura[i]) se establece aleatoriamente dentro de un rango dado de "Tmin" a "Tmax". Luego se genera una nueva temperatura independientemente para cada camello, lo que introduce aleatoriedad en el proceso.
Las reservas del camello (supply [i]) disminuyen dependiendo de la distancia recorrida. Se calcula como el valor de reservas anterior multiplicado por el coeficiente (1,0 - omega * journeyRatio). El parámetro "omega" controla la velocidad a la que disminuyen las reservas. Cuanto mayor sea el valor "omega" y el "journeyRatio" (es decir, cuanto más lejos haya llegado el algoritmo), más rápido disminuirán las reservas.
La resistencia del camello (resistencia [i]) disminuye dependiendo tanto de la temperatura como de la distancia recorrida. La resistencia se calcula como el valor de resistencia anterior multiplicado por (1,0 - temperatureRatio) * (1,0 - journeyRatio). temperatureRatio es la relación entre la temperatura actual del camello y la temperatura máxima "Tmax". Cuanto más alta sea la temperatura y más avance el algoritmo, más disminuirá la resistencia.
De esta forma, el método cambia dinámicamente las características de cada camello usando tanto variables aleatorias (temperatura) como información sobre el progreso del algoritmo (distancia recorrida). Estos cambios afectan la forma en que los camellos exploran el espacio de búsqueda.
//+----------------------------------------------------------------------------+ //| Обновление факторов (температура, запас, выносливость) | //+----------------------------------------------------------------------------+ void C_AO_CAm::UpdateFactors () { double journeyRatio = (double)traveledSteps / (double)totalSteps; for (int i = 0; i < popSize; i++) { // Обновление температуры - случайное значение в диапазоне [Tmin, Tmax], // формула (1): Tnow = (Tmax - Tmin) * Rand(0,1) + Tmin temperature [i] = u.RNDfromCI (Tmin, Tmax); // Обновление запаса - уменьшается с течением времени, // формула (2): Snow = Spast * (1 - ω * Traveled steps / Total journey steps) supply [i] = supply [i] * (1.0 - omega * journeyRatio); // Обновление выносливости - зависит от температуры и времени, // формула (4): Enow = Epast * (1 - Tnow/Tmax) * (1 - Traveled steps / Total journey steps) double temperatureRatio = temperature [i] / Tmax; endurance [i] = endurance [i] * (1.0 - temperatureRatio) * (1.0 - journeyRatio); } } //——————————————————————————————————————————————————————————————————————————————
El método "UpdatePositions" está diseñado para actualizar las posiciones de los camellos en cada paso del algoritmo de optimización. Modela los movimientos y eventos aleatorios que influyen en la actualización de decisiones.
Los pasos principales del método implican la iteración en toda la población de camellos. Para cada camello se efectúan los siguientes pasos:
-
Con cierta probabilidad (por ejemplo, debido a condiciones desfavorables como arenas movedizas, tormentas o altas temperaturas) el camello se considera fallecido. En este caso, su posición en el espacio se genera aleatoriamente de nuevo dentro del rango aceptable y se ajusta según los pasos mínimos.
-
Si el camello no "muere", su nueva posición se determina usando un modelo de paseo aleatorio. Para cada dimensión de coordenadas, se genera un factor aleatorio "delta" en el rango [-1, 1] para modelar la variación aleatoria.
-
La nueva coordenada se calcula como el valor anterior con la adición de un término modificador que considera el paseo aleatorio, las características actuales del camello (resistencia y reservas) y la diferencia entre la coordenada actual y la posición del oasis. En este caso se considera la influencia de los factores de resistencia “endurance” y las reservas “supply”.
-
Después de calcular una nueva coordenada, se verifica si se encuentra fuera del rango aceptable.
Como resultado de este proceso, las posiciones de los camellos cambian dinámicamente, simulando sus movimientos en el espacio de búsqueda considerando factores aleatorios y su estado interno (resistencia y reservas). Estas actualizaciones ayudan al algoritmo a explorar el espacio de soluciones de forma más eficiente, evitando mínimos locales y facilitando la búsqueda de la solución óptima.
El código comentado de la funcionalidad original de la "muerte" y recreación de la posición no se utiliza en la versión modificada actual del algoritmo.
Cambios clave en la versión modificada: la comprobación de la "muerte" del camello ahora se realiza para cada coordenada por separado, en lugar de para el camello en su totalidad; en lugar de generar de forma completamente aleatoria una nueva posición, se utiliza una distribución normal (gaussiana) alrededor de la mejor solución (cB); la función "GaussDistribution" crea una nueva posición basada en una distribución normal centrada en la mejor solución, lo que permite una exploración más específica de áreas prometedoras.
//+----------------------------------------------------------------------------+ //| Обновление позиций верблюдов | //+----------------------------------------------------------------------------+ void C_AO_CAm::UpdatePositions () { for (int i = 0; i < popSize; i++) { /* // Проверка на "смерть" верблюда (quicksand, storm, etc.) if (u.RNDprobab () < dyingRate) { // Генерируем новую позицию случайным образом for (int c = 0; c < coords; c++) { a [i].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } continue; } */ // Обновление позиции------------------------------------------------------- double delta = u.RNDfromCI (-1.0, 1.0); // Фактор случайного блуждания // Обновляем каждую координату for (int c = 0; c < coords; c++) { /* // Применяем формулу обновления из статьи double enduranceFactor = (1.0 - endurance [i] / initialEndurance); double supplyFactor = MathExp (1.0 - supply [i] / initialSupply); // Обновление позиции a [i].c [c] = a [i].c [c] + delta * enduranceFactor * supplyFactor * (cB [c] - a [i].c [c]); // Проверка на выход за границы и корректировка до допустимого значения a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); */ // Проверка на "смерть" верблюда (quicksand, storm, etc.) if (u.RNDprobab () < dyingRate) { // Генерируем новую позицию относительно координаты оазиса по нормальному распределению a [i].c [c] = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 8); } else { // Применяем формулу обновления из статьи double enduranceFactor = (1.0 - endurance [i] / initialEndurance); double supplyFactor = MathExp (1.0 - supply [i] / initialSupply); // Обновление позиции a [i].c [c] = a [i].c [c] + delta * enduranceFactor * supplyFactor * (cB [c] - a [i].c [c]); } // Проверка на выход за границы и корректировка до допустимого значения a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————
El método "ApplyOasisEffect" simula el efecto de un oasis en la condición de los camellos durante la búsqueda. Su tarea principal consiste en determinar si el camello ha descubierto un oasis y, al hacerlo, mejorar la condición de sus recursos.
Al pasar por la población completa, el método prueba dos condiciones para cada camello. La primera es la probabilidad de encontrar un oasis, que está determinada por un número aleatorio y depende del parámetro "alpha". Cuanto mayor sea el "alpha", mayor será la posibilidad de detección. La segunda consistirá en comprobar si el valor actual de la función de aptitud (o la calidad de la solución) del camello es mejor que el que tenía en la iteración anterior. Esto garantiza que el oasis sólo afecte a aquellos camellos cuyo rendimiento realmente haya mejorado.
Si se cumplen ambas condiciones, se considera que el camello ha descubierto un oasis. En este caso, sus reservas y resistencia se restablecen a sus valores originales. De esta forma, el oasis favorece la recuperación de los recursos del camello y le permite continuar explorando activamente el espacio de búsqueda con mayor eficiencia.
La idea general del método consiste en simular la capacidad de los camellos para encontrar oasis, lo cual les permite recuperarse y continuar la búsqueda, mejorando sus posibilidades de alcanzar el óptimo global.
//+----------------------------------------------------------------------------+ //| Применение эффекта оазиса (обновление запасов и выносливости) | //+----------------------------------------------------------------------------+ void C_AO_CAm::ApplyOasisEffect () { for (int i = 0; i < popSize; i++) { // Условие для обнаружения оазиса: // 1) Верблюд должен "видеть" оазис (случайная вероятность, зависящая от alpha) // 2) Текущее решение должно быть лучше, чем в предыдущей итерации if (u.RNDprobab () > (1.0 - alpha) && a [i].f > a [i].fP) { // Обнаружен оазис, пополняем запасы и выносливость supply [i] = initialSupply; endurance [i] = initialEndurance; } } } //——————————————————————————————————————————————————————————————————————————————
Resultados de las pruebas
Como podemos ver, al ejecutar la versión original del algoritmo CA, obtenemos un máximo de 32,56%.
=============================
5 Hilly's; Func runs: 10000; result: 0.5872886802671936
25 Hilly's; Func runs: 10000; result: 0.3896531310299016
500 Hilly's; Func runs: 10000; result: 0.3412707468979892
=============================
5 Forest's; Func runs: 10000; result: 0.5248302942062708
25 Forest's; Func runs: 10000; result: 0,2760893244414008
500 Forest's; Func runs: 10000; result: 0,18881523788478266
=============================
5 Megacity's; Func runs: 10000; result: 0.3507692307692308
25 Megacity's; Func runs: 10000; result: 0.16676923076923078
500 Megacity's; Func runs: 10000; result: 0.10464615384615475
=============================
All score: 2.93013 (32.56%)
El algoritmo modificado muestra mejores resultados:
CAm|Camel Algorithm|50.0|50.0|100.0|0.8|0.01|0.9|
=============================
5 Hilly's; Func runs: 10000; result: 0,786842172387197
25 Hilly's; Func runs: 10000; result: 0.560421361070792
500 Hilly's; Func runs: 10000; result: 0.3513297097198401
=============================
5 Forest's; Func runs: 10000; result: 0.8277193604225209
25 Forest's; Func runs: 10000; result: 0.5604138230149972
500 Forest's; Func runs: 10000; result: 0,24335977579892912
=============================
5 Megacity's; Func runs: 10000; result: 0.6484615384615386
25 Megacity's; Func runs: 10000; result: 0.33092307692307693
500 Megacity's; Func runs: 10000; result: 0,13417692307692433
=============================
All score: 4.44365 (49.37%)
Le presentamos la visualización del funcionamiento del algoritmo para las versiones CA y CAm, para una mejor comprensión de las diferencias entre ambas. Las dos versiones exhiben la característica de "agrupamiento" de la lógica del algoritmo en la vecindad de soluciones potencialmente buenas.

CA en la función de prueba de Hilly

CAm en la función de prueba Hilly

CA en la función de prueba Forest

CAm en la función de prueba Forest

CA en la función de prueba Megacity

CAm em la función de prueba Megacity
La versión modificada del algoritmo ocupa el puesto 35 en el ranking de algoritmos de optimización de la población; la versión original se presenta solo con fines informativos y no tiene un número de clasificación.
| № | AO | Description | Hilly | Hilly Final | Forest | Forest Final | Megacity (discrete) | Megacity Final | Final Resultado | % de MAX | ||||||
| 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | ||||||||
| 1 | ANS | across neighbourhood search | 0,94948 | 0,84776 | 0,43857 | 2,23581 | 1,00000 | 0,92334 | 0,39988 | 2,32323 | 0,70923 | 0,63477 | 0,23091 | 1,57491 | 6,134 | 68,15 |
| 2 | CLA | code lock algorithm (joo) | 0,95345 | 0,87107 | 0,37590 | 2,20042 | 0,98942 | 0,91709 | 0,31642 | 2,22294 | 0,79692 | 0,69385 | 0,19303 | 1,68380 | 6,107 | 67,86 |
| 3 | AMOm | animal migration optimization M | 0,90358 | 0,84317 | 0,46284 | 2,20959 | 0,99001 | 0,92436 | 0,46598 | 2,38034 | 0,56769 | 0,59132 | 0,23773 | 1,39675 | 5,987 | 66,52 |
| 4 | (P+O)ES | (P+O) evolution strategies | 0,92256 | 0,88101 | 0,40021 | 2,20379 | 0,97750 | 0,87490 | 0,31945 | 2,17185 | 0,67385 | 0,62985 | 0,18634 | 1,49003 | 5,866 | 65,17 |
| 5 | CTA | comet tail algorithm (joo) | 0,95346 | 0,86319 | 0,27770 | 2,09435 | 0,99794 | 0,85740 | 0,33949 | 2,19484 | 0,88769 | 0,56431 | 0,10512 | 1,55712 | 5,846 | 64,96 |
| 6 | TETA | time evolution travel algorithm (joo) | 0,91362 | 0,82349 | 0,31990 | 2,05701 | 0,97096 | 0,89532 | 0,29324 | 2,15952 | 0,73462 | 0,68569 | 0,16021 | 1,58052 | 5,797 | 64,41 |
| 7 | SDSm | stochastic diffusion search M | 0,93066 | 0,85445 | 0,39476 | 2,17988 | 0,99983 | 0,89244 | 0,19619 | 2,08846 | 0,72333 | 0,61100 | 0,10670 | 1,44103 | 5,709 | 63,44 |
| 8 | BOAm | billiards optimization algorithm M | 0,95757 | 0,82599 | 0,25235 | 2,03590 | 1,00000 | 0,90036 | 0,30502 | 2,20538 | 0,73538 | 0,52523 | 0,09563 | 1,35625 | 5,598 | 62,19 |
| 9 | AAm | archery algorithm M | 0,91744 | 0,70876 | 0,42160 | 2,04780 | 0,92527 | 0,75802 | 0,35328 | 2,03657 | 0,67385 | 0,55200 | 0,23738 | 1,46323 | 5,548 | 61,64 |
| 10 | ESG | evolution of social groups (joo) | 0,99906 | 0,79654 | 0,35056 | 2,14616 | 1,00000 | 0,82863 | 0,13102 | 1,95965 | 0,82333 | 0,55300 | 0,04725 | 1,42358 | 5,529 | 61,44 |
| 11 | SIA | simulated isotropic annealing (joo) | 0,95784 | 0,84264 | 0,41465 | 2,21513 | 0,98239 | 0,79586 | 0,20507 | 1,98332 | 0,68667 | 0,49300 | 0,09053 | 1,27020 | 5,469 | 60,76 |
| 12 | ACS | artificial cooperative search | 0,75547 | 0,74744 | 0,30407 | 1,80698 | 1,00000 | 0,88861 | 0,22413 | 2,11274 | 0,69077 | 0,48185 | 0,13322 | 1,30583 | 5,226 | 58,06 |
| 13 | DA | dialectical algorithm | 0,86183 | 0,70033 | 0,33724 | 1,89940 | 0,98163 | 0,72772 | 0,28718 | 1,99653 | 0,70308 | 0,45292 | 0,16367 | 1,31967 | 5,216 | 57,95 |
| 14 | BHAm | black hole algorithm M | 0,75236 | 0,76675 | 0.34583 | 1,86493 | 0.93593 | 0.80152 | 0,27177 | 2,00923 | 0.65077 | 0.51646 | 0,15472 | 1,32195 | 5.196 | 57.73 |
| 15 | ASO | anarchy society optimization | 0,84872 | 0,74646 | 0,31465 | 1,90983 | 0,96148 | 0,79150 | 0,23803 | 1,99101 | 0,57077 | 0,54062 | 0,16614 | 1,27752 | 5,178 | 57,54 |
| 16 | RFO | royal flush optimization (joo) | 0,83361 | 0,73742 | 0,34629 | 1,91733 | 0,89424 | 0,73824 | 0,24098 | 1,87346 | 0,63154 | 0,50292 | 0,16421 | 1,29867 | 5,089 | 56,55 |
| 17 | AOSm | búsqueda de orbitales atómicos M | 0,80232 | 0,70449 | 0,31021 | 1,81702 | 0,85660 | 0,69451 | 0,21996 | 1,77107 | 0,74615 | 0,52862 | 0,14358 | 1,41835 | 5,006 | 55,63 |
| 18 | TSEA | turtle shell evolution algorithm (joo) | 0,96798 | 0,64480 | 0,29672 | 1,90949 | 0,99449 | 0,61981 | 0,22708 | 1,84139 | 0,69077 | 0,42646 | 0,13598 | 1,25322 | 5,004 | 55,60 |
| 19 | DE | differential evolution | 0,95044 | 0,61674 | 0,30308 | 1,87026 | 0,95317 | 0,78896 | 0,16652 | 1,90865 | 0,78667 | 0,36033 | 0,02953 | 1,17653 | 4,955 | 55,06 |
| 20 | SRA | successful restaurateur algorithm (joo) | 0,96883 | 0,63455 | 0,29217 | 1,89555 | 0,94637 | 0,55506 | 0,19124 | 1,69267 | 0,74923 | 0,44031 | 0,12526 | 1,31480 | 4,903 | 54,48 |
| 21 | CRO | chemical reaction optimisation | 0,94629 | 0,66112 | 0,29853 | 1,90593 | 0,87906 | 0,58422 | 0,21146 | 1,67473 | 0,75846 | 0,42646 | 0,12686 | 1,31178 | 4,892 | 54,36 |
| 22 | BIO | blood inheritance optimization (joo) | 0,81568 | 0,65336 | 0,30877 | 1,77781 | 0,89937 | 0,65319 | 0,21760 | 1,77016 | 0,67846 | 0,47631 | 0,13902 | 1,29378 | 4,842 | 53,80 |
| 23 | BSA | bird swarm algorithm | 0,89306 | 0,64900 | 0,26250 | 1,80455 | 0,92420 | 0,71121 | 0,24939 | 1,88479 | 0,69385 | 0,32615 | 0,10012 | 1,12012 | 4,809 | 53,44 |
| 24 | HS | harmony search | 0,86509 | 0,68782 | 0,32527 | 1,87818 | 0,99999 | 0,68002 | 0,09590 | 1,77592 | 0,62000 | 0,42267 | 0,05458 | 1,09725 | 4,751 | 52,79 |
| 25 | SSG | saplings sowing and growing | 0,77839 | 0,64925 | 0,39543 | 1,82308 | 0,85973 | 0,62467 | 0,17429 | 1,65869 | 0,64667 | 0,44133 | 0,10598 | 1,19398 | 4,676 | 51,95 |
| 26 | BCOm | bacterial chemotaxis optimization M | 0,75953 | 0,62268 | 0,31483 | 1,69704 | 0,89378 | 0,61339 | 0,22542 | 1,73259 | 0,65385 | 0,42092 | 0,14435 | 1,21912 | 4,649 | 51,65 |
| 27 | ABO | african buffalo optimization | 0,83337 | 0,62247 | 0,29964 | 1,75548 | 0,92170 | 0,58618 | 0,19723 | 1,70511 | 0,61000 | 0,43154 | 0,13225 | 1,17378 | 4,634 | 51,49 |
| 28 | (PO)ES | (PO) evolution strategies | 0,79025 | 0,62647 | 0,42935 | 1,84606 | 0,87616 | 0,60943 | 0,19591 | 1,68151 | 0,59000 | 0,37933 | 0,11322 | 1,08255 | 4,610 | 51,22 |
| 29 | FBA | fractal-based Algorithm | 0,79000 | 0.65134 | 0,28965 | 1.73099 | 0.87158 | 0.56823 | 0,18877 | 1.62858 | 0,61077 | 0.46062 | 0,12398 | 1,19537 | 4.555 | 50.61 |
| 30 | TSm | tabu search M | 0,87795 | 0,61431 | 0,29104 | 1,78330 | 0,92885 | 0,51844 | 0,19054 | 1,63783 | 0,61077 | 0,38215 | 0,12157 | 1,11449 | 4,536 | 50,40 |
| 31 | BSO | brain storm optimization | 0,93736 | 0,57616 | 0,29688 | 1,81041 | 0,93131 | 0,55866 | 0,23537 | 1,72534 | 0,55231 | 0,29077 | 0,11914 | 0,96222 | 4,498 | 49,98 |
| 32 | WOAm | wale optimization algorithm M | 0,84521 | 0,56298 | 0,26263 | 1,67081 | 0,93100 | 0,52278 | 0,16365 | 1,61743 | 0,66308 | 0,41138 | 0,11357 | 1,18803 | 4,476 | 49,74 |
| 33 | AEFA | artificial electric field algorithm | 0,87700 | 0,61753 | 0,25235 | 1,74688 | 0,92729 | 0,72698 | 0,18064 | 1,83490 | 0,66615 | 0,11631 | 0,09508 | 0,87754 | 4,459 | 49,55 |
| 34 | AEO | artificial ecosystem-based optimization algorithm | 0,91380 | 0,46713 | 0,26470 | 1,64563 | 0,90223 | 0,43705 | 0,21400 | 1,55327 | 0,66154 | 0,30800 | 0,28563 | 1,25517 | 4,454 | 49,49 |
| 35 | Leva | camel algorithm M | 0,78684 | 0.56042 | 0.35133 | 1.69859 | 0.82772 | 0.56041 | 0,24336 | 1.63149 | 0.64846 | 0.33092 | 0,13418 | 1,11356 | 4.444 | 49.37 |
| 36 | ACOm | ant colony optimization M | 0,88190 | 0,66127 | 0,30377 | 1,84693 | 0,85873 | 0,58680 | 0,15051 | 1,59604 | 0,59667 | 0,37333 | 0,02472 | 0,99472 | 4,438 | 49,31 |
| 37 | BFO-GA | bacterial foraging optimization - ga | 0,89150 | 0,55111 | 0,31529 | 1,75790 | 0,96982 | 0,39612 | 0,06305 | 1,42899 | 0,72667 | 0,27500 | 0,03525 | 1,03692 | 4,224 | 46,93 |
| 38 | SOA | simple optimization algorithm | 0.91520 | 0.46976 | 0.27089 | 1,65585 | 0.89675 | 0.37401 | 0.16984 | 1,44060 | 0.69538 | 0.28031 | 0.10852 | 1,08422 | 4.181 | 46,45 |
| 39 | ABH | artificial bee hive algorithm | 0,84131 | 0,54227 | 0,26304 | 1,64663 | 0,87858 | 0,47779 | 0,17181 | 1,52818 | 0,50923 | 0,33877 | 0,10397 | 0,95197 | 4.127 | 45,85 |
| 40 | ACMO | atmospheric cloud model optimization | 0,90321 | 0,48546 | 0,30403 | 1,69270 | 0,80268 | 0,37857 | 0,19178 | 1,37303 | 0,62308 | 0,24400 | 0,10795 | 0,97503 | 4,041 | 44,90 |
| 41 | ADAMm | adaptive moment estimation M | 0.88635 | 0.44766 | 0,26613 | 1.60014 | 0.84497 | 0.38493 | 0.16889 | 1,39880 | 0,66154 | 0.27046 | 0.10594 | 1,03794 | 4.037 | 44.85 |
| 42 | CGO | chaos game optimization | 0,57256 | 0,37158 | 0,32018 | 1,26432 | 0,61176 | 0,61931 | 0,62161 | 1,85267 | 0,37538 | 0,21923 | 0,19028 | 0,78490 | 3,902 | 43,35 |
| 43 | ATAm | artificial tribe algorithm M | 0.71771 | 0.55304 | 0,25235 | 1,52310 | 0.82491 | 0.55904 | 0,20473 | 1,58867 | 0,44000 | 0,18615 | 0.09411 | 0.72026 | 3.832 | 42.58 |
| 44 | CROm | coral reefs optimization M | 0,78512 | 0,46032 | 0,25958 | 1,50502 | 0,86688 | 0,35297 | 0,16267 | 1,38252 | 0,63231 | 0,26738 | 0,10734 | 1,00703 | 3,895 | 43,27 |
| 45 | CFO | central force optimization | 0,60961 | 0,54958 | 0,27831 | 1,43750 | 0,63418 | 0,46833 | 0,22541 | 1,32792 | 0,57231 | 0,23477 | 0,09586 | 0,90294 | 3,668 | 40,76 |
| CALIFORNIA | camel algorithm | 0.58729 | 0,38965 | 0.34127 | 1.31821 | 0.52483 | 0,27609 | 0,18882 | 0.98974 | 0.35077 | 0,16677 | 0,10465 | 0.62219 | 2.930 | 32.56 | |
| R.W. | neuroboids optimization algorithm 2(joo) | 0.48754 | 0.32159 | 0.25781 | 1,06694 | 0.37554 | 0,21944 | 0,15877 | 0,75375 | 0.27969 | 0,14917 | 0.09847 | 0.52734 | 2.348 | 26.09 | |
Conclusiones
La versión modificada del algoritmo de camello CAm demuestra un rendimiento significativamente mayor que el original, gracias a una serie de mejoras clave.
En primer lugar, se ha cambiado fundamentalmente el mecanismo de "muerte" del camello: en lugar de generar nuevas soluciones de forma completamente aleatoria, se usa una distribución gaussiana alrededor de la mejor solución encontrada, lo que garantiza una búsqueda específica e intensiva en las áreas más prometedoras.
El seguimiento preciso de las mejoras de decisiones usando el almacenamiento de valores anteriores de la función de aptitud para cada camello garantiza una aplicación más precisa del efecto oasis. El aumento de la flexibilidad del algoritmo agregando "Tmin" a los parámetros ajustables y utilizando un parámetro externo para determinar el número total de pasos hace que CAm sea más adaptable a diferentes tipos de problemas de optimización.
Estas mejoras integrales, tomadas en conjunto, suponen una mejora significativa en la versión modificada en cuanto a la velocidad de convergencia, la precisión de las soluciones encontradas y la estabilidad del funcionamiento.

Figura 2. Clasificación por colores de los algoritmos según las pruebas respectivas

Figura 3. Histograma de los resultados de las pruebas de algoritmos (en una escala de 0 a 100, cuanto más mejor, donde 100 es el máximo resultado teórico posible, el script para calcular la tabla de puntuación está en el archivo)
Ventajas y desventajas del algoritmo CAm:
Ventajas:
- Es rápido.
- Implementación sencilla.
- Buenos resultados en funciones de dimensionalidades grandes y medias (especialmente en problemas "suaves").
Desventajas:
- Gran número de parámetros externos.
- Dispersión de resultados en funciones de baja dimensionalidad.
Adjuntamos al artículo un archivo con las versiones actuales de los códigos de los algoritmos. El autor de este artículo no se responsabiliza de la exactitud absoluta de la descripción de los algoritmos canónicos, muchos de ellos han sido modificados para mejorar las capacidades de búsqueda. Las conclusiones y juicios presentados en los artículos se basan en los resultados de los experimentos realizados.
Programas usados en el artículo
| # | Nombre | Tipo | Descripción |
|---|---|---|---|
| 1 | #C_AO.mqh | Archivo de inclusión | Clase padre de algoritmos de optimización basados en la población |
| 2 | #C_AO_enum.mqh | Archivo de inclusión | Enumeración de los algoritmos de optimización basados en la población |
| 3 | TestFunctions.mqh | Archivo de inclusión | Biblioteca de funciones de prueba |
| 4 | TestStandFunctions.mqh | Archivo de inclusión | Biblioteca de funciones del banco de pruebas |
| 5 | Utilities.mqh | Archivo de inclusión | Biblioteca de funciones auxiliares |
| 6 | CalculationTestResults.mqh | Archivo de inclusión | Script para calcular los resultados en una tabla comparativa |
| 7 | Testing AOs.mq5 | Script | Banco de pruebas único para todos los algoritmos de optimización basados en la población |
| 8 | Simple use of population optimization algorithms.mq5 | Script | Ejemplo sencillo de utilización de algoritmos de optimización basados en la población sin visualización |
| 9 | Test_AO_CAm.mq5 | Script | Banco de pruebas para CAm |
Traducción del ruso hecha por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/ru/articles/18057
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Visión por computadora para el trading (Parte 2): Complicamos la arquitectura para el análisis 2D de imágenes RGB
Creación de clases de negociación similares a MQL5 en Python para MetaTrader 5
Particularidades del trabajo con números del tipo double en MQL4
Criterio de independencia de Hilbert-Schmidt (HSIC)
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso