Algoritmo do camelo — Camel Algorithm (CA)
Conteúdo
Introdução
Nas últimas décadas, surgiu uma quantidade significativa de algoritmos de otimização inspirados em fenômenos naturais e no comportamento de animais. Essas abordagens bioinspiradas mostraram resultados excelentes em muitas tarefas. Neste artigo, vamos analisar um novo algoritmo de otimização chamado Camel Algorithm (CA), baseado nas estratégias de sobrevivência e deslocamento dos camelos em condições extremas do deserto. O algoritmo foi desenvolvido e apresentado em 2016 por dois cientistas: Mohammed Khalid Ibrahim e Ramzy Salim Ali.
Os camelos possuem características fisiológicas únicas e adaptações comportamentais que lhes permitem se orientar e sobreviver de forma eficiente nas duras condições do deserto, com recursos limitados, temperaturas extremas e um ambiente em constante mudança. O algoritmo CA modela aspectos-chave desse comportamento, como a influência da temperatura, o gerenciamento das reservas de água e alimento, a resistência, o efeito dos "oásis" (áreas promissoras de busca), bem como a interação em grupo dentro da caravana.
Nós, como de costume, vamos destrinchar toda a "estrutura interna" do algoritmo original, fazer uma modificação e testar ambas as versões em funções de teste, registrando os resultados em nossa tabela de classificação de algoritmos de otimização.
Implementação do algoritmo
Imagine uma caravana de camelos partindo em uma jornada através de um enorme deserto. O objetivo deles é encontrar oásis com água e alimento, escondidos entre areias intermináveis. Foi exatamente essa jornada que inspirou os autores a criar o algoritmo de otimização "Camel Algorithm" (CA).
O algoritmo imita a situação de como esses animais incríveis sobrevivem e encontram recursos nas duras condições do deserto. Cada camelo no algoritmo é uma solução potencial que explora o espaço de busca (o deserto), tentando encontrar a solução ideal (o oásis mais rico).
As caravanas de camelos viajam juntas não por acaso, pois essa é uma estratégia de sobrevivência. No algoritmo, a população de "camelos" (soluções potenciais) troca informações sobre as melhores rotas encontradas, o que é muito semelhante à forma como os camelos reais em uma caravana seguem caminhos já testados até as fontes de água.
Elementos-chave:
Temperatura (T) — um fator aleatório que influencia o comportamento dos camelos. No deserto, a temperatura varia de noites frescas a dias escaldantes, influenciando a velocidade e a direção do movimento dos camelos. A capacidade única dos camelos de se adaptarem a temperaturas extremas, desde noites frias até dias quentes no deserto, serviu de inspiração para o parâmetro de "temperatura" no algoritmo. Esse parâmetro introduz um elemento de aleatoriedade e adaptabilidade, o que ajuda a evitar ótimos locais, de forma análoga a como os camelos precisam adaptar sua rota às condições em constante mudança.
Reservas (S) — água e alimento, que se esgotam gradualmente ao longo do caminho. Os camelos evoluíram para sobreviver em algumas das condições mais severas do planeta. A capacidade deles de distribuir recursos de forma eficiente (água e alimento) é refletida diretamente no algoritmo por meio do parâmetro "supply", que diminui ao longo da "jornada" e influencia a estratégia de busca. Quanto mais tempo o camelo viaja sem encontrar um oásis, menos forças lhe restam. Essa característica torna o algoritmo especialmente eficiente em tarefas com recursos computacionais limitados.
Resistência (E) — a energia do camelo, que depende da temperatura e da duração da viagem. O sol escaldante esgota lentamente as forças da caravana. Os camelos são conhecidos por sua resistência excepcional, pela capacidade de percorrer grandes distâncias com recursos mínimos. No algoritmo, o parâmetro "endurance" influencia a capacidade do agente de explorar o espaço de soluções. Ele diminui gradualmente e atua no equilíbrio entre a exploração de novas regiões e a utilização das soluções promissoras já encontradas.
Efeito de oásis — quando o camelo encontra um local promissor (a melhor solução), suas reservas e resistência são restauradas, permitindo continuar a exploração. No algoritmo, quando uma solução é encontrada, os parâmetros "supply" e "endurance" são reabastecidos, o que permite examinar essa região de forma mais detalhada, exatamente como um camelo permanece em um oásis para recuperar as forças, portanto, essa é uma das características mais interessantes do algoritmo.
Caminhada aleatória — desvios em relação ao caminho principal que ajudam a explorar novos territórios.
Como mostrado na ilustração abaixo, um grupo de cinco camelos procura um oásis rico no deserto. Inicialmente, eles estão em locais diferentes e se movem em direções distintas:
Camelo 1 se desloca para o norte, mas devido à alta temperatura sua velocidade diminui, e ele precisa fazer mais paradas.Camelo 2 encontra um pequeno oásis (ótimo local) com algumas reservas de comida e água. Ele informa os outros sobre sua descoberta, mas continua a busca, suspeitando que exista um oásis maior em algum lugar.
Camelo 3 vagueia por uma região relativamente plana, suas reservas diminuem gradualmente, mas ele continua explorando novas direções.
Camelo 4 entra em uma área com temperatura muito elevada, o que reduz significativamente sua resistência. No entanto, a caminhada aleatória o ajuda a sair dessa região.
Camelo 5, usando informações de outros camelos e uma direção favorável da caminhada aleatória, encontra o oásis mais rico (ótimo global).

Figura 1. Ilustração do funcionamento do algoritmo CA
Vamos escrever o pseudocódigo do funcionamento do algoritmo CA:
// Inicialização dos parâmetros
Inicializar:
popSize = tamanho da população (caravana de camelos)
Tmin = temperatura mínima
Tmax = temperatura máxima
omega = fator de carga para as reservas
dyingRate = taxa de "morte" dos camelos
alpha = parâmetro de visibilidade para o efeito de oásis
initialSupply = reserva inicial de água e alimento (normalmente 1.0)
initialEndurance = resistência inicial (normalmente 1.0)
totalSteps = número total de passos do caminho
traveledSteps = 0 (valor inicial dos passos percorridos)
// Inicialização da população inicial
Criar a caravana inicial de camelos (várias soluções):
Para cada camelo i de 1 até popSize:
Gerar uma solução aleatória dentro do intervalo permitido
Definir os valores iniciais:
temperature [i] = valor aleatório entre Tmin e Tmax
supply [i] = initialSupply
endurance [i] = initialEndurance
Calcular a adaptabilidade (fitness) de cada camelo na caravana
Encontrar a melhor solução atual
// Ciclo principal de otimização
Enquanto (traveledSteps < totalSteps):
traveledSteps++
// Para cada camelo na caravana
Para i de 1 até popSize:
// 1. Atualizar os fatores (temperatura, reservas, resistência)
// Fórmula (1): Tnow = (Tmax - Tmin) * Rand(0,1) + Tmin
temperature [i] = CalculateTemperature (i)
// Fórmula (2): Snow = Spast (1 - ω * Traveled steps / Total journey steps)
supply [i] = CalculateSupply (i)
// Fórmula (4): Enow = Epast (1 - Tnow / Tmax) * (1 - Traveled steps / Total journey steps)
endurance [i] = CalculateEndurance (i)
// 2. Verificação de "morte" do camelo
Se (número_aleatório < dyingRate):
Gerar uma nova solução aleatória para o camelo i
Continuar para a próxima iteração
// 3. Atualizar a posição do camelo
delta = número aleatório no intervalo [-1, 1] // fator de caminhada aleatória
Salvar as coordenadas antigas do camelo
// Para cada coordenada
Para cada coordenada c:
// Calcular os fatores para a fórmula de atualização
enduranceFactor = (1.0 - endurance [i] / initialEndurance)
supplyFactor = exp(1.0 - supply [i] / initialSupply)
// Atualizar a posição pela fórmula (6)
new_position [c] = old_position [c] + delta * enduranceFactor * supplyFactor * (best_position [c] - old_position [c])
// Verificar se saiu dos limites e corrigir se necessário
new_position [c] = Ajustar para o intervalo permitido
// 4. Aplicar o efeito de oásis
Se (número_aleatório > (1.0 - alpha) e fitness_new > fitness_old):
// Oásis encontrado, reabastecer reservas e resistência
supply [i] = initialSupply
endurance [i] = initialEndurance
// Classificar os camelos e encontrar a melhor solução
Atualizar a melhor solução
// Retornar a melhor solução final
Agora podemos começar a escrever o código, dentro do qual será considerada tanto a versão original dos autores (parte das linhas ficará comentada) quanto a minha modificação, voltada para melhorar a lógica de funcionamento do algoritmo. Vamos escrever a classe "C_AO_CAm", que representará a implementação do algoritmo CAm e herdará da classe base "C_AO".
A classe contém parâmetros característicos do algoritmo, como o tamanho da população, a temperatura mínima e máxima, o fator de carga, a taxa de "morte" dos camelos e o parâmetro de visibilidade. Esses parâmetros podem ser definidos durante a inicialização e são convenientemente configurados por meio de um array de parâmetros.
O construtor da classe define as propriedades principais do algoritmo, incluindo o nome, a descrição e o link para a fonte da ideia, além de inicializar o array de parâmetros. No método "SetParams", esses parâmetros podem ser atualizados durante a execução.
A classe implementa métodos de inicialização da população, dos passos de deslocamento dos camelos, bem como de sua revisão, atualização de fatores e dos efeitos associados aos oásis, ou seja, tudo o que modela o comportamento dos camelos no deserto e busca soluções ótimas. As principais propriedades da classe são os arrays que armazenam a temperatura de cada camelo, suas reservas de água e alimento, a resistência, assim como os contadores de passos percorridos e do total de passos. Há também variáveis que definem os níveis iniciais de reservas e resistência, que normalmente são inicializadas no início da execução do algoritmo.
De modo geral, essa classe implementa uma versão modificada do algoritmo de otimização baseado no comportamento de uma caravana de camelos, onde a "temperatura" e as "reservas" modelam estados intermediários da busca, e a dinâmica de movimento e morte dos camelos ajuda a encontrar a solução de forma eficiente.
//—————————————————————————————————————————————————————————————————————————————— 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/ru/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 (); }; //——————————————————————————————————————————————————————————————————————————————
O método "Init" é destinado à inicialização do algoritmo CAm. Durante a execução desse método, ocorre a preparação das estruturas de dados e dos parâmetros necessários para o trabalho posterior. As principais etapas do método incluem a chamada da inicialização padrão, que define os intervalos e os passos de variação das variáveis de busca. Caso a inicialização não seja bem-sucedida, o método é finalizado com erro.
Em seguida, ocorre a alocação de memória para os arrays que armazenam os parâmetros de cada camelo, temperatura, reservas de água e alimento, resistência, cujo tamanho é igual ao tamanho da população. Esses arrays são necessários para modelar o comportamento dos camelos durante a otimização. São definidos os valores iniciais de reservas e resistência, o contador de passos percorridos é definido como zero, assim como o número total de passos, correspondente ao 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; } //——————————————————————————————————————————————————————————————————————————————
O método "Moving" implementa o processo iterativo do algoritmo, sendo responsável pela atualização dos estados e dos deslocamentos dos camelos. Primeiramente, ele verifica se a primeira iteração já foi executada; caso contrário, inicializa a população inicial de camelos e marca que a inicialização foi concluída.
Em cada passo subsequente, o contador de passos percorridos é incrementado e, em seguida, ocorre a execução sequencial das seguintes ações:
- Atualização dos fatores, como temperatura, reservas de recursos e resistência de cada camelo, o que é importante para modelar o comportamento dinâmico e o processo de busca.
- Atualização das posições dos camelos no espaço de busca, isto é, o deslocamento na direção que potencialmente melhora a solução.
- Aplicação do efeito de oásis, no qual os camelos podem aumentar suas reservas e restaurar a resistência, o que ajuda a evitar mínimos locais e estimula uma exploração mais complexa do espaço.
Ao final de cada passo, ocorre o salvamento do valor da função de adaptabilidade para cada camelo, de modo que seja possível comparar o estado atual com o anterior e, com base nisso, tomar decisões posteriores.
//+----------------------------------------------------------------------------+ //| Основной метод оптимизации | //+----------------------------------------------------------------------------+ 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; } //——————————————————————————————————————————————————————————————————————————————
O método "Revision" é responsável por atualizar a melhor solução encontrada na população atual de camelos. Ele percorre todos os camelos da população e compara o valor da função objetivo (fitness) de cada camelo com o melhor valor atual. Se o valor da função de adaptabilidade do camelo atual (a [i].f) for melhor do que o melhor valor corrente (fB), ocorre a atualização:
- "fB" recebe o novo melhor valor (a [i].f).
- A posição (coordenadas, parâmetros) do camelo que atingiu o melhor valor é copiada das coordenadas do camelo atual (a [i].c) para o array de coordenadas da melhor solução (cB).
Após a conclusão do ciclo por todos os camelos da população, "fB" e "cB" conterão o valor e as coordenadas da melhor solução encontrada na iteração atual.
//+----------------------------------------------------------------------------+ //| Обновление лучшего решения | //+----------------------------------------------------------------------------+ 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); } } } //——————————————————————————————————————————————————————————————————————————————
O método "InitializePopulation" é destinado à formação da população inicial de camelos no algoritmo de otimização. Ele cria uma distribuição uniforme das soluções iniciais por todo o espaço de busca permitido.
As principais etapas do método incluem o percurso de toda a população, isto é, de todos os camelos. Para cada camelo, ocorre a geração de coordenadas aleatórias dentro dos intervalos permitidos para cada variável (cada coordenada). Essas coordenadas são escolhidas de forma aleatória para cobrir uniformemente todo o intervalo admissível.
Após a geração das coordenadas, cada uma delas é arredondada para o passo permitido mais próximo, garantindo a conformidade da busca com as restrições de discretização. Isso é feito para que as soluções iniciais correspondam exatamente aos intervalos e passos permitidos. Além disso, para cada camelo são definidos os valores iniciais de parâmetros como reserva de água e resistência, conforme os valores padrão previamente estabelecidos para toda a população.
Como resultado da execução do método, é criada uma população inicial de soluções, distribuída de forma uniforme por todo o espaço de busca, o que contribui para uma organização eficiente do início do processo de otimização.
//+----------------------------------------------------------------------------+ //| Инициализация начальной популяции | //+----------------------------------------------------------------------------+ 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; } } //——————————————————————————————————————————————————————————————————————————————
O método "UpdateFactors" na classe "C_AO_CAm" é responsável por atualizar os principais fatores que influenciam o comportamento de cada "camelo" na população: temperatura, reservas e resistência. Esses fatores são alterados dinamicamente a cada iteração do algoritmo e influenciam o processo de busca pela solução ótima.
Inicialmente, é calculado o "journeyRatio", que representa a razão entre os passos percorridos "traveledSteps" e o número total de passos "totalSteps". Esse valor reflete o progresso da execução do algoritmo. Para cada camelo (i de 0 até popSize - 1), a temperatura (temperature [i]) é definida aleatoriamente dentro do intervalo especificado entre "Tmin" e "Tmax". A nova temperatura é gerada de forma independente para cada camelo, introduzindo aleatoriedade no processo.
A reserva do camelo (supply [i]) é reduzida em função do caminho percorrido. Ela é calculada como o valor anterior da reserva multiplicado pelo coeficiente (1.0 - omega * journeyRatio). O parâmetro "omega" controla a velocidade de redução da reserva. Quanto maior o valor de "omega" e quanto maior o "journeyRatio" (ou seja, quanto mais avançado estiver o algoritmo), mais rapidamente a reserva diminui.
A resistência do camelo (endurance [i]) diminui tanto em função da temperatura quanto do caminho percorrido. A resistência é calculada como o valor anterior da resistência multiplicado por (1.0 - temperatureRatio) * (1.0 - journeyRatio). O temperatureRatio é a razão entre a temperatura atual do camelo e a temperatura máxima "Tmax". Quanto maior a temperatura e quanto mais avançado estiver o algoritmo, maior será a redução da resistência.
Dessa forma, o método altera dinamicamente as características de cada camelo, utilizando tanto grandezas aleatórias (temperatura) quanto informações sobre o progresso do algoritmo (caminho percorrido). Essas mudanças influenciam diretamente a forma como os camelos exploram o espaço de busca.
//+----------------------------------------------------------------------------+ //| Обновление факторов (температура, запас, выносливость) | //+----------------------------------------------------------------------------+ 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); } } //——————————————————————————————————————————————————————————————————————————————
O método "UpdatePositions" é destinado à atualização das posições dos camelos em cada passo do algoritmo de otimização. Ele modela os deslocamentos e os eventos aleatórios que afetam a atualização das soluções.
As principais etapas do método incluem a iteração por toda a população de camelos. Para cada camelo, são realizadas as seguintes ações:
-
Com certa probabilidade, por exemplo, devido a condições desfavoráveis como areias movediças, tempestades ou temperaturas elevadas, o camelo é considerado morto. Nesse caso, sua posição no espaço é gerada novamente de forma aleatória dentro do intervalo permitido e ajustada de acordo com os passos mínimos.
-
Se o camelo não "morre", sua nova posição é determinada por meio de um modelo de caminhada aleatória. Para cada dimensão de coordenada, é gerado um fator aleatório "delta" no intervalo [-1, 1], que modela uma variação aleatória.
-
A nova coordenada é calculada como o valor antigo acrescido de um termo modificador, que leva em consideração a caminhada aleatória, as características atuais do camelo (resistência e reserva), bem como a diferença entre a coordenada atual e a posição do oásis. Nesse processo, é considerado o impacto dos fatores de esgotamento, resistência "endurance" e reserva "supply".
-
Após o cálculo da nova coordenada, ela é verificada quanto a possíveis saídas dos limites permitidos do intervalo.
Como resultado desse processo, as posições dos camelos são alteradas dinamicamente, modelando seus deslocamentos no espaço de busca levando em conta fatores aleatórios e o estado interno (resistência e reserva). Essas atualizações ajudam o algoritmo a explorar o espaço de soluções de forma mais eficiente, evitando mínimos locais e favorecendo a busca pela solução ótima.
O código comentado do funcional original de "morte" e recriação da posição não é utilizado na versão modificada atual do algoritmo.
As principais alterações da versão modificada são: a verificação de "morte" do camelo agora é realizada separadamente para cada coordenada, e não para o camelo inteiro; em vez de uma geração totalmente aleatória de uma nova posição, é utilizada uma distribuição normal (gaussiana) em torno da melhor solução (cB); a função "GaussDistribution" cria uma nova posição segundo uma distribuição normal com centro na melhor solução, o que proporciona uma exploração mais direcionada das áreas promissoras.
//+----------------------------------------------------------------------------+ //| Обновление позиций верблюдов | //+----------------------------------------------------------------------------+ 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]); } } } //——————————————————————————————————————————————————————————————————————————————
O método "ApplyOasisEffect" modela a influência do oásis sobre o estado dos camelos durante o processo de busca. Sua principal tarefa é determinar se um camelo descobriu um oásis e, ao mesmo tempo, melhorar o estado de seus recursos.
Percorrendo toda a população, o método verifica para cada camelo duas condições. A primeira é a probabilidade de detectar um oásis, que é definida por um número aleatório e depende do parâmetro "alpha". Quanto maior o valor de "alpha", maiores são as chances de detecção. A segunda é a verificação de que o valor atual da função de adaptabilidade (ou a qualidade da solução) do camelo é melhor do que aquele obtido na iteração anterior. Isso garante que o efeito do oásis atue apenas sobre os camelos cujos resultados realmente melhoraram.
Se ambas as condições forem satisfeitas, considera-se que o camelo encontrou um oásis. Nesse caso, suas reservas "supply" e sua resistência "endurance" são restauradas aos valores iniciais. Dessa forma, o oásis contribui para a recuperação dos recursos do camelo e permite que ele continue explorando ativamente o espaço de busca com maior eficiência.
O significado geral do método é modelar a capacidade dos camelos de encontrar oásis, o que lhes dá a oportunidade de se recuperar e continuar a atividade de busca, aumentando as chances de alcançar o ótimo 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 dos testes
Como pode ser observado, ao utilizar a versão original do algoritmo CA, ele atinge no máximo 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%)
O algoritmo com a modificação apresenta resultados mais elevados:
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%)
A visualização do funcionamento do algoritmo é apresentada para as versões CA e CAm, permitindo uma melhor percepção das diferenças entre os dois algoritmos. Ambas as versões demonstram o “agrupamento” característico da lógica do algoritmo nas proximidades de soluções potencialmente boas.

CA na função de teste Hilly

CAm na função de teste Hilly

CA na função de teste Forest

CAm na função de teste Forest

CA na função de teste Megacity

CAm na função de teste Megacity
A versão modificada do algoritmo ocupa a 35ª posição no ranking de algoritmos populacionais de otimização; a versão original é apresentada apenas para fins informativos e não possui número no ranking.
| № | AO | Description | Hilly | Hilly Final | Forest | Forest Final | Megacity (discrete) | Megacity Final | Final Result | % of 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 ptimization 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 | atomic orbital search 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 | CAm | 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 | ABHA | 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 |
| CA | 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 | |
| RW | 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 | |
Considerações finais
A versão modificada do algoritmo do camelo, CAm, demonstra indicadores de eficiência significativamente mais elevados em comparação com a versão original, graças a uma série de aprimoramentos-chave.
Antes de tudo, o mecanismo de "morte" do camelo foi alterado de forma fundamental — em vez de uma geração completamente aleatória de novas soluções, é utilizada uma distribuição gaussiana em torno da melhor solução encontrada, o que garante uma busca direcionada e intensiva nas regiões mais promissoras.
O acompanhamento preciso das melhorias das soluções por meio do armazenamento dos valores anteriores da função de adaptabilidade para cada camelo garante uma aplicação mais correta do efeito de oásis. O aumento da flexibilidade do algoritmo, obtido com a adição de "Tmin" aos parâmetros configuráveis e com o uso de um parâmetro externo para definir o número total de passos, torna o CAm mais adaptável a diferentes tipos de tarefas de otimização.
Essas melhorias abrangentes, em conjunto, proporcionam um avanço significativo da versão modificada em termos de velocidade de convergência, precisão das soluções encontradas e estabilidade de funcionamento.

Figura 2. Graduação de cores dos algoritmos nos testes correspondentes

Figura 3. Histograma dos resultados dos testes dos algoritmos (na escala de 0 a 100, quanto maior, melhor, onde 100 — resultado teórico máximo possível, no arquivo há um script para o cálculo da tabela de classificação)
Vantagens e desvantagens do algoritmo CAm:
Vantagens:
- Rápido.
- Implementação simples.
- Bons resultados em funções de média e grande dimensionalidade, especialmente em tarefas "suaves".
Desvantagens:
- Grande quantidade de parâmetros externos.
- Dispersão dos resultados em funções de pequena dimensionalidade.
Um arquivo compactado com as versões atualizadas dos códigos dos algoritmos está anexado ao artigo. O autor do artigo não se responsabiliza pela precisão absoluta na descrição dos algoritmos canônicos, pois muitos deles foram modificados para melhorar as capacidades de busca. As conclusões e julgamentos apresentados nos artigos baseiam-se nos resultados dos experimentos realizados.
Programas utilizados no artigo
| # | Nome | Tipo | Descrição |
|---|---|---|---|
| 1 | #C_AO.mqh | Arquivo de inclusão | Classe base dos algoritmos populacionais de otimização |
| 2 | #C_AO_enum.mqh | Arquivo de inclusão | Enumeração dos algoritmos populacionais de otimização |
| 3 | TestFunctions.mqh | Arquivo de inclusão | Biblioteca de funções de teste |
| 4 | TestStandFunctions.mqh | Arquivo de inclusão | Biblioteca de funções do ambiente de testes |
| 5 | Utilities.mqh | Arquivo de inclusão | Biblioteca de funções auxiliares |
| 6 | CalculationTestResults.mqh | Arquivo de inclusão | Script para cálculo dos resultados na tabela comparativa |
| 7 | Testing AOs.mq5 | Script | Ambiente de testes unificado para todos os algoritmos populacionais de otimização |
| 8 | Simple use of population optimization algorithms.mq5 | Script | Exemplo simples de uso de algoritmos populacionais de otimização sem visualização |
| 9 | Test_AO_CAm.mq5 | Script | Ambiente de testes para o CAm |
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/18057
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Ciência de Dados e ML (Parte 33): Dataframe do Pandas em MQL5, Coleta de Dados para Uso em ML facilitada
Critério de Independência de Hilbert-Schmidt (HSIC)
Automatizando Estratégias de Trading em MQL5 (Parte 5): Desenvolvendo a Estratégia Adaptive Crossover RSI Trading Suite
Construindo Expert Advisors Auto-Otimizáveis em MQL5 (Parte 5): Regras de Negociação Auto Adaptativas
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso