Русский
preview
Algoritmo do camelo — Camel Algorithm (CA)

Algoritmo do camelo — Camel Algorithm (CA)

MetaTrader 5Negociação |
23 0
Andrey Dik
Andrey Dik

Conteúdo

  1. Introdução
  2. Implementação do algoritmo
  3. Resultados dos testes


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).

    camel-algorithm

    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:

    1. 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.
    2. Atualização das posições dos camelos no espaço de busca, isto é, o deslocamento na direção que potencialmente melhora a solução.
    3. 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:

    1. "fB" recebe o novo melhor valor (a [i].f).
    2. 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:

    1. 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.

    2. 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.

    3. 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".

    4. 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%

    CA|Camel Algorithm|50.0|50.0|100.0|0.8|0.1|0.5|
    ===============================================
    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.

    Hilly

    CA na função de teste Hilly

      Hilly

    CAm na função de teste Hilly

    Forest

    CA na função de teste Forest

        Forest

    CAm na função de teste Forest

    Megacity

    CA na função de teste Megacity

    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.

    chart

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

    chart

    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:

    1. Rápido.
    2. Implementação simples.
    3. Bons resultados em funções de média e grande dimensionalidade, especialmente em tarefas "suaves".

    Desvantagens:

    1. Grande quantidade de parâmetros externos.
    2. 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

    Arquivos anexados |
    CA.ZIP (278.59 KB)
    Ciência de Dados e ML (Parte 33): Dataframe do Pandas em MQL5, Coleta de Dados para Uso em ML facilitada Ciência de Dados e ML (Parte 33): Dataframe do Pandas em MQL5, Coleta de Dados para Uso em ML facilitada
    Ao trabalhar com modelos de aprendizado de máquina, é essencial garantir consistência nos dados usados para treinamento, validação e testes. Neste artigo, criaremos nossa própria versão da biblioteca Pandas em MQL5 para garantir uma abordagem unificada para o tratamento de dados de aprendizado de máquina, assegurando que os mesmos dados sejam aplicados dentro e fora do MQL5, onde ocorre a maior parte do treinamento.
    Critério de Independência de Hilbert-Schmidt (HSIC) Critério de Independência de Hilbert-Schmidt (HSIC)
    O artigo examina o teste estatístico não paramétrico HSIC (Hilbert-Schmidt Independence Criterion) destinado a identificar dependências lineares e não lineares nos dados. São propostas implementações de dois algoritmos para o cálculo do HSIC na linguagem MQL5: o teste exato por permutação e a aproximação gama. A eficácia do método é demonstrada em dados sintéticos que modelam uma relação não linear entre os atributos e a variável-alvo.
    Automatizando Estratégias de Trading em MQL5 (Parte 5): Desenvolvendo a Estratégia Adaptive Crossover RSI Trading Suite Automatizando Estratégias de Trading em MQL5 (Parte 5): Desenvolvendo a Estratégia Adaptive Crossover RSI Trading Suite
    Neste artigo, desenvolvemos o Sistema Adaptive Crossover RSI Trading Suite, que utiliza cruzamentos de médias móveis de 14 e 50 períodos para geração de sinais, confirmados por um filtro de RSI de 14 períodos. O sistema inclui um filtro de dias de negociação, setas de sinal com anotações e um painel em tempo real para monitoramento. Essa abordagem garante precisão e adaptabilidade no trading automatizado.
    Construindo Expert Advisors Auto-Otimizáveis em MQL5 (Parte 5): Regras de Negociação Auto Adaptativas Construindo Expert Advisors Auto-Otimizáveis em MQL5 (Parte 5): Regras de Negociação Auto Adaptativas
    As melhores práticas, que definem como usar um indicador com segurança, nem sempre são fáceis de seguir. Condições de mercado calmas podem, surpreendentemente, produzir leituras no indicador que não se qualificam como um sinal de negociação, levando à perda de oportunidades para traders algorítmicos. Este artigo irá sugerir uma solução potencial para esse problema, à medida que discutimos como construir aplicações de negociação capazes de adaptar suas regras de negociação aos dados de mercado disponíveis.