Русский Español
preview
Algoritmo de tribo artificial (Artificial Tribe Algorithm, ATA)

Algoritmo de tribo artificial (Artificial Tribe Algorithm, ATA)

MetaTrader 5Exemplos |
226 0
Andrey Dik
Andrey Dik

Conteúdo

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


Introdução

Com o rápido avanço das tecnologias e o aumento da complexidade das tarefas de otimização, cientistas e pesquisadores continuam buscando inspiração na natureza. Um exemplo notável dessa abordagem é o algoritmo de tribo artificial (Artificial Tribe Algorithm, ATA), criado pelos cientistas T. Chen, Y. Wang e C. Li, e publicado em 2012. Inspirado no comportamento de tribos, o ATA utiliza dois mecanismos principais: propagação e migração, permitindo adaptação a condições variáveis e encontrando soluções ideais para os mais diversos problemas. Imagine vastas planícies onde grupos humanos, como seus antepassados distantes, se unem em busca de melhores recursos. Eles migram, compartilham conhecimento e experiências, criando estratégias únicas para resolver desafios complexos. Esse comportamento serviu de base para o desenvolvimento do ATA – um algoritmo que combina harmoniosamente dois mecanismos centrais: propagação e migração.

O algoritmo de tribo artificial representa um método completamente novo de otimização, baseado nos princípios dos algoritmos inteligentes biónicos. Ele simula o comportamento das tribos naturais, utilizando suas capacidades de reprodução e migração para alcançar soluções ideais. Nesse algoritmo, a tribo é composta por indivíduos que interagem entre si para encontrar o ótimo global.


Implementação do algoritmo

O funcionamento do algoritmo ATA começa com a definição dos parâmetros e a inicialização aleatória da tribo, após o que é calculado o valor de adaptabilidade. Em seguida, o contador de iterações é incrementado, e a situação atual da tribo é avaliada. Se a situação for favorável (a diferença no valor ótimo da adaptabilidade entre gerações for maior que um critério definido), realiza-se o comportamento de reprodução, onde os indivíduos trocam informações. Caso contrário, é utilizado o comportamento de migração, no qual os indivíduos se movem considerando tanto sua própria experiência quanto a de toda a tribo. A migração não pode ocorrer de forma contínua, para evitar dispersão excessiva. Depois, o valor de adaptabilidade é novamente calculado e comparado com os melhores valores registrados da tribo e de cada indivíduo. Se for encontrada uma solução melhor, ela é armazenada na memória. Verifica-se se as condições de término foram atendidas e, se sim, a iteração é encerrada. Caso contrário, o processo retorna à etapa de avaliação da situação.

A inclusão de informação global no ATA dá peso à experiência histórica da tribo, o que ajuda a encontrar melhores soluções e aprimorar a capacidade de busca. O aumento do peso da experiência da tribo contribui para elevar a eficiência do algoritmo, acelerando sua convergência. Para isso, o ATA introduz um peso inercial global, que reforça as habilidades de busca e acelera o processo.

A principal inovação do ATA é a existência de um sistema de comportamento duplo, que se adapta conforme a situação: a reprodução é usada para uma diversificação aprofundada quando o progresso é bom, enquanto a migração é ativada ao se ficar preso em ótimos locais, promovendo uma atividade de busca mais aprofundada. Também é essencial a combinação de aprendizado individual e social. A memória individual (Xs) é usada durante a migração, enquanto a memória global (Xg) é ponderada por um coeficiente inercial AT_w. Na reprodução, os parceiros são escolhidos aleatoriamente, o que ajuda a aumentar a diversidade e a acelerar a busca.

O sistema de parâmetros do ATA é simples, mas eficaz. Ele controla o tamanho da população (tribe_size), o critério de troca de comportamento (AT_criterion) e a influência global na busca (AT_w), tornando o algoritmo uma ferramenta flexível e poderosa, que, segundo os autores, compete facilmente com algoritmos mais complexos, especialmente quando se trabalha com populações pequenas.

Os principais componentes do algoritmo incluem o comportamento de reprodução, que é aplicado quando há bom progresso, ou seja, quando a diferença na adaptabilidade é maior que o critério estabelecido. Nesse caso, os indivíduos trocam informações parciais. O comportamento de migração é usado em situações desfavoráveis, quando a diferença na adaptabilidade é pequena, e envolve deslocamento com base na experiência individual e global, considerando o peso da inércia para reforçar a busca global. O critério de existência avalia as mudanças na melhor adaptabilidade entre as iterações: se as mudanças forem significativas, utiliza-se a reprodução; se forem insignificantes, ocorre a migração.

O algoritmo também inclui um sistema de atualização de memória, que monitora as melhores posições tanto de indivíduos isolados quanto da tribo como um todo. Essas posições são atualizadas sempre que novas soluções melhores são encontradas.

As particularidades do projeto do ATA residem na simplicidade dos parâmetros, na integração do aprendizado individual e social, bem como na troca auto-adaptativa entre reprodução e migração. O peso inercial global melhora a capacidade de busca, acelerando a descoberta de soluções ideais.

Assim, as regras do comportamento individual podem ser descritas da seguinte forma:

1. Propagação. O indivíduo utiliza a informação presente na população para formar o material genético das futuras gerações. Se a situação atual do ambiente for favorável, o indivíduo escolhe aleatoriamente outro membro da tribo e realiza o cruzamento para gerar a próxima geração por meio da troca de informação genética.

2. Migração. Se a situação atual for desfavorável (o que indica que a diferença intergeracional no valor ótimo da adaptabilidade é menor que o critério existente), o indivíduo se desloca com base na sua própria experiência e na experiência histórica da tribo, realizando a migração da tribo.

Visualmente, as fases-chave que ocorrem na população do algoritmo podem ser representadas esquematicamente como na figura 1.

ATA_2

Figura 1. Fases de deslocamento dos indivíduos na população do algoritmo ATA

Vamos escrever o pseudocódigo do algoritmo ATA:

// Algoritmo da tribo artificial
// Parâmetros principais:
// tribe_size - tamanho da população da tribo
// ATA_criterion - valor limite do critério de existência
// ATA_w - peso inercial global
// X - vetor de posição do indivíduo
// Xs - melhor posição histórica do indivíduo
// Xg - melhor posição histórica global da tribo

Algoritmo ATA:
    Inicialização:
        Criar uma tribo com tribe_size indivíduos com posições X aleatórias
        Calcular os valores iniciais de adaptabilidade para todos os indivíduos
        Inicializar Xs e Xg com as melhores posições encontradas
        iteração = 0
        
    Enquanto (iteração < max_iterações):
        iteração = iteração + 1
        
        // Verificar se a situação é favorável para a existência
        diferença = |melhor_adaptabilidade_atual - melhor_adaptabilidade_anterior|
        
        Se (diferença > ATA_criterion):
            // Situação favorável – aplicar comportamento de propagação
            Para cada indivíduo i:
                // Escolher um parceiro j aleatório da tribo
                j = aleatório (1, tribe_size) onde j ≠ i
                
                // Fórmulas de propagação:
                r1 = aleatório (0,1)
                Yi+1 = r1 * Yj + (1 - r1) * Xi // Nova posição do parceiro
                Xi+1 = r1 * Xi + (1 - r1) * Yi // Nova posição do indivíduo
                
        Senão:
            // Situação desfavorável – aplicar comportamento de migração
            Para cada indivíduo i:
                // Fórmula de migração:
                r1 = aleatório (0,1)
                r2 = aleatório (0,1)
                Xi+1 = Xi + r1 * (Xs - Xi) + ATA_w * r2 * (Xg - Xi)
                
        // Atualizar os valores de adaptabilidade e as melhores posições
        Para cada indivíduo i:
            Calcular nova_adaptabilidade para Xi
            
            Se nova_adaptabilidade for melhor que a melhor_adaptabilidade_do_indivíduo:
                Atualizar Xs para o indivíduo i
                
            Se nova_adaptabilidade for melhor que a melhor_adaptabilidade_global:
                Atualizar Xg
                
        Salvar melhor_adaptabilidade_atual para a próxima iteração
        
    Retornar Xg como a melhor solução encontrada

ATA

Figura 2. Esquema lógico do funcionamento do algoritmo ATA

Definimos a classe C_AO_ATA, que implementa o algoritmo ATA. Vamos descrever brevemente seu conteúdo:

Herança e membros principais:
  • A classe herda da classe base C_AO
  • Contém um destrutor e um construtor
O construtor inicializa os parâmetros básicos:
  • popSize = 50 (tamanho da tribo)
  • AT_criterion = 0.3 (critério de favorabilidade da situação)
  • AT_w = 1.46 (peso inercial)
Métodos:
  • SetParams () – define os parâmetros a partir do array "params"
  • Init () – inicialização com os intervalos de busca
  • Moving () – implementação do movimento dos indivíduos
  • Revision () – avaliação e atualização das soluções
Membros privados:
  • prevBestFitness – armazena o melhor valor anterior para comparação

Essa é a estrutura básica do algoritmo, onde são definidos todos os parâmetros e métodos necessários para seu funcionamento.

//——————————————————————————————————————————————————————————————————————————————
class C_AO_ATA : public C_AO
{
  public: //--------------------------------------------------------------------
  ~C_AO_ATA () { }
  C_AO_ATA ()
  {
    ao_name = "ATA";
    ao_desc = "Artificial Tribe Algorithm";
    ao_link = "https://www.mql5.com/ru/articles/16588";

    popSize      = 50;   // Размер популяции
    AT_criterion = 0.3;  // Критерий оценки текущей ситуации
    AT_w         = 1.46; // Глобальный инерционный вес

    ArrayResize (params, 3);

    // Инициализация параметров
    params [0].name = "popSize";      params [0].val = popSize;
    params [1].name = "AT_criterion"; params [1].val = AT_criterion;
    params [2].name = "AT_w";         params [2].val = AT_w;
  }

  void SetParams () // Метод для установки параметров
  {
    popSize      = (int)params [0].val;
    AT_criterion = params     [1].val;
    AT_w         = params     [2].val;
  }

  bool Init (const double &rangeMinP  [], // Минимальный диапазон поиска
             const double &rangeMaxP  [], // Максимальный диапазон поиска
             const double &rangeStepP [], // Шаг поиска
             const int     epochsP = 0);  // Количество эпох

  void Moving   ();       // Метод перемещения
  void Revision ();       // Метод ревизии

  //----------------------------------------------------------------------------
  double AT_criterion;    // Критерий оценки текущей ситуации
  double AT_w;            // Глобальный инерционный вес

  private: //-------------------------------------------------------------------
  double prevBestFitness; //Предыдущее лучшее решение
};
//——————————————————————————————————————————————————————————————————————————————

O método "Init" da classe C_AO_ATA é responsável por inicializar o algoritmo. Vamos analisar suas partes:

Parâmetros do método:
  • rangeMinP [] – array de valores mínimos para cada dimensão da busca
  • rangeMaxP [] – array de valores máximos
  • rangeStepP [] – array de passos de discretização
  • epochsP – número de épocas (padrão é 0)
Ações principais:
  • Chama "StandardInit" da classe base para inicializar parâmetros padrão
  • Se "StandardInit" retornar "false", o método é interrompido
  • Define "prevBestFitness" como "-DBL_MAX" (para tarefa de maximização)
Retorno:
  • true em caso de inicialização bem-sucedida
  • false se a inicialização padrão falhar

Essa é uma implementação mínima de inicialização, que prepara o algoritmo para funcionar.

//——————————————————————————————————————————————————————————————————————————————
bool C_AO_ATA::Init (const double &rangeMinP  [], // Минимальный диапазон поиска
                     const double &rangeMaxP  [], // Максимальный диапазон поиска
                     const double &rangeStepP [], // Шаг поиска
                     const int     epochsP = 0)   // Количество эпох
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false; // Инициализация стандартных параметров

  //----------------------------------------------------------------------------
  prevBestFitness = -DBL_MAX;
  return true;
}
//——————————————————————————————————————————————————————————————————————————————

O método "Moving()" é responsável pelo deslocamento dos indivíduos da tribo e é dividido em duas partes principais:

Se for a primeira execução (revision = false):
  • Posiciona aleatoriamente todos os indivíduos no espaço de busca
  • ajusta suas posições para valores discretos permitidos
  • marca que o posicionamento inicial foi feito (revision = true)
Se não for a primeira execução, calcula o critério da situação atual "diff" e, se a situação for boa (diff > AT_criterion):
  • cada indivíduo escolhe um parceiro aleatório
  • eles trocam informações sobre suas posições
  • formam novas posições com base nessa troca
Se a situação for ruim (diff ≤ AT_criterion), cada indivíduo se move considerando:
  • sua melhor posição
  • a melhor posição global
  • o peso inercial "AT_w"

Em qualquer deslocamento, todas as novas posições são verificadas e ajustadas para valores válidos dentro dos intervalos definidos. Além disso, há um detalhe importante: como o critério de avaliação da situação é um parâmetro externo e adimensional, é necessário normalizar a diferença entre a melhor adaptabilidade atual e a anterior pela diferença entre a melhor adaptabilidade histórica e a pior: diff = (fB - prevBestFitness) / (fB - fW). É justamente por isso que este algoritmo monitora não apenas a melhor solução global, mas também a pior solução global.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_ATA::Moving ()
{
  // Начальное случайное позиционирование
  if (!revision) // Если еще не было ревизии
  {
    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]); // Приведение к дискретным значениям
      }
    }

    revision = true; // Установка флага ревизии
    return;          // Выход из метода
  }

  //----------------------------------------------------------------------------
  // Проверка критерия существования
  double diff = (fB - prevBestFitness) / (fB - fW);

  double Xi   = 0.0;
  double Xi_1 = 0.0;
  double Yi   = 0.0;
  double Yi_1 = 0.0;
  double Xs   = 0.0;
  double Xg   = 0.0;
  int    p    = 0;
  double r1   = 0.0;
  double r2   = 0.0;

  if (diff > AT_criterion)
  {
    // Поведение распространения (хорошая ситуация)
    for (int i = 0; i < popSize; i++)
    {
      for (int c = 0; c < coords; c++)
      {
        p  = u.RNDminusOne (popSize);
        r1 = u.RNDprobab ();

        Xi = a [i].cP [c];
        Yi = a [p].cP [c];

        Xi_1 = r1 * Xi + (1.0 - r1) * Yi;
        Yi_1 = r1 * Yi + (1.0 - r1) * Xi;

        a [i].c [c] = u.SeInDiSp  (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
        a [p].c [c] = u.SeInDiSp  (Yi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }
  }
  else
  {
    // Поведение миграции (плохая ситуация)
    for (int i = 0; i < popSize; i++)
    {
      for (int c = 0; c < coords; c++)
      {
        r1 = u.RNDprobab ();
        r2 = u.RNDprobab ();

        Xi = a [i].cP [c];
        Xs = a [i].cB [c];
        Xg = cB [c];

        Xi_1 = Xi + r1 * (Xs - Xi) + AT_w * r2 * (Xg - Xi);

        a [i].c [c] = u.SeInDiSp (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

O método "Revision()" é responsável por avaliar e atualizar as melhores soluções após o deslocamento dos indivíduos. Veja o que ele faz:

Para todos os indivíduos da tribo:
    • verifica se houve melhoria na melhor solução global (fB)
    • atualiza a pior solução encontrada (fW)
    • verifica e atualiza a melhor solução pessoal de cada indivíduo (a[i].fB)
    • salva as posições atuais como anteriores (em cP)
    Se uma nova melhor solução for encontrada (indB diferente de -1):
      • salva o valor anterior da melhor solução (prevBestFitness = tempB)
      • copia as coordenadas do melhor indivíduo para a melhor solução global (cB)

      Basicamente, esse é o método de “revisão” do estado atual da tribo, onde todos os indicadores importantes são atualizados: valores globais melhores/piores, melhores valores pessoais de cada indivíduo e o histórico de posições é preservado.

      //——————————————————————————————————————————————————————————————————————————————
      void C_AO_ATA::Revision ()
      {
        //----------------------------------------------------------------------------
        int    indB  = -1;                // Индекс лучшей частицы
        double tempB = fB;
      
        for (int i = 0; i < popSize; i++) // Для каждой частицы
        {
          if (a [i].f > fB)               // Если значение функции лучше, чем текущее лучшее
          {
            fB   = a [i].f;               // Обновление лучшего значения функции
            indB = i;                     // Сохранение индекса лучшей частицы
          }
      
          if (a [i].f < fW)               // Если значение функции хуже, чем текущее худшее
          {
            fW   = a [i].f;               // Обновление худшего значения функции
          }
      
          if (a [i].f > a [i].fB)
          {
            a [i].fB = a [i].f;
            ArrayCopy (a [i].cB, a [i].c, 0, 0, WHOLE_ARRAY);
          }
      
          ArrayCopy (a [i].cP, a [i].c, 0, 0, WHOLE_ARRAY);
        }
      
        if (indB != -1)
        {
          prevBestFitness = tempB;
          ArrayCopy (cB, a [indB].c, 0, 0, WHOLE_ARRAY); // Копирование координат лучшей частицы
        }
      }
      //——————————————————————————————————————————————————————————————————————————————

      Passamos agora aos resultados dos testes do algoritmo ATA na bancada de avaliação.

      ATA|Artificial Tribe Algorithm|50.0|0.3|0.5|
      =============================
      5 Hilly's; Func runs: 10000; result: 0.540711768815426
      25 Hilly's; Func runs: 10000; result: 0.31409437631469717
      500 Hilly's; Func runs: 10000; result: 0.2512638813618161
      =============================
      5 Forest's; Func runs: 10000; result: 0.40309649266442193
      25 Forest's; Func runs: 10000; result: 0.2572536671383149
      500 Forest's; Func runs: 10000; result: 0.18349902023635473
      =============================
      5 Megacity's; Func runs: 10000; result: 0.24
      25 Megacity's; Func runs: 10000; result: 0.13600000000000004
      500 Megacity's; Func runs: 10000; result: 0.09518461538461616
      =============================
      All score: 2.42110 (26.90%)

      Como é possível ver nos resultados impressos do algoritmo e na visualização, com esses indicadores o algoritmo infelizmente não consegue entrar na nossa tabela de classificação. Na visualização abaixo, ficam evidentes as limitações do algoritmo para escapar de armadilhas locais onde o ATA fica preso. O algoritmo demonstra claramente uma falta de diversidade na população de soluções, o que leva à sua degeneração.

      Hilly Orig

      ATAm na função de teste Hilly

      Vamos tentar melhorar o algoritmo ATA, focando na falta de diversidade das soluções dentro da população. Esse é um aspecto importante, pois a diversidade é fundamental para uma busca eficaz no espaço de soluções. Na nossa modificação, introduziremos uma probabilidade dinâmica, que dependerá do estado de adaptabilidade da população.

      Quando a população se comprime em uma faixa estreita do espaço de soluções, isso pode fazer com que o algoritmo fique preso em um ótimo local. Assim como na versão original do algoritmo, vamos monitorar a diferença entre as melhores soluções globais atual e anterior, mas, se essa diferença for muito pequena, isso será um sinal de que a população está pouco diversificada e, possivelmente, se aproximando do colapso das soluções.

      Para evitar essa situação, vamos, com determinada probabilidade, eliminar indivíduos que estejam muito distantes da solução global atual. Isso ocorrerá dentro dos limites permitidos do problema, garantindo o cumprimento das condições e evitando extrapolações. Utilizaremos uma distribuição normal para determinar o quão distantes esses indivíduos estarão da solução global atual ao serem descartados.

      Curiosamente, quanto maior a diferença entre as melhores soluções atual e anterior (representada como "diff"), maior será a probabilidade dessas eliminações. Isso nos permitirá reagir de forma adaptativa ao estado da população: quando ela começar a se prender, utilizaremos com mais intensidade a fase de migração, o que, por sua vez, aumentará as chances de escapar de ótimos locais e encontrar soluções mais adequadas.

      Dessa forma, nossa modificação do algoritmo ATA contribuirá não apenas para manter a diversidade das soluções, mas também para melhorar a eficácia geral da busca no espaço de soluções. Isso pode resultar em resultados mais consistentes e soluções de maior qualidade.

      //——————————————————————————————————————————————————————————————————————————————
      void C_AO_ATAm::Moving ()
      {
        // Начальное случайное позиционирование
        if (!revision) // Если еще не было ревизии
        {
          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]); // Приведение к дискретным значениям
            }
          }
      
          revision = true; // Установка флага ревизии
          return;          // Выход из метода
        }
      
        //----------------------------------------------------------------------------
        // Проверка критерия существования
        double diff = (fB - prevBestFitness) / (fB - fW);
      
        double Xi   = 0.0;
        double Xi_1 = 0.0;
        double Yi   = 0.0;
        double Yi_1 = 0.0;
        double Xs   = 0.0;
        double Xg   = 0.0;
        int    p    = 0;
        double r1   = 0.0;
        double r2   = 0.0;
      
        if (diff > AT_criterion)
        {
          // Поведение распространения (хорошая ситуация)
          for (int i = 0; i < popSize; i++)
          {
            for (int c = 0; c < coords; c++)
            {
              p  = u.RNDminusOne (popSize);
              r1 = u.RNDprobab ();
      
              Xi = a [i].cP [c];
              Yi = a [p].cP [c];
      
              Xi_1 = r1 * Xi + (1.0 - r1) * Yi;
              Yi_1 = r1 * Yi + (1.0 - r1) * Xi;
      
              a [i].c [c] = u.SeInDiSp  (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
              a [p].c [c] = u.SeInDiSp  (Yi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
            }
          }
        }
        else
        {
          // Поведение миграции (плохая ситуация)
          for (int i = 0; i < popSize; i++)
          {
            for (int c = 0; c < coords; c++)
            {
              if (u.RNDprobab () < diff)
              {
                Xi_1 = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 1);
                a [i].c [c] = u.SeInDiSp (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
              }
              else
              {
                r1 = u.RNDprobab ();
                r2 = u.RNDprobab ();
      
                Xi = a [i].cP [c];
                Xs = a [i].cB [c];
                Xg = cB [c];
      
                Xi_1 = Xi + r1 * (Xs - Xi) + AT_w * r2 * (Xg - Xi);
      
                a [i].c [c] = u.SeInDiSp (Xi_1, rangeMin [c], rangeMax [c], rangeStep [c]);
              }
            }
          }
        }
      }
      //——————————————————————————————————————————————————————————————————————————————


      Resultados dos testes

      Resultados da versão modificada do algoritmo ATAm:

      ATAm|Artificial Tribe Algorithm M|50.0|0.9|0.8|
      =============================
      5 Hilly's; Func runs: 10000; result: 0.7177133636761123
      25 Hilly's; Func runs: 10000; result: 0.553035897955171
      500 Hilly's; Func runs: 10000; result: 0.25234636879284034
      =============================
      5 Forest's; Func runs: 10000; result: 0.8249072382287125
      25 Forest's; Func runs: 10000; result: 0.5590392181296365
      500 Forest's; Func runs: 10000; result: 0.2047284499286112
      =============================
      5 Megacity's; Func runs: 10000; result: 0.43999999999999995
      25 Megacity's; Func runs: 10000; result: 0.18615384615384617
      500 Megacity's; Func runs: 10000; result: 0.09410769230769304
      =============================
      All score: 3.83203 (42.58%)

      Desta vez, os resultados foram significativamente mais promissores e já são dignos de inclusão na tabela de classificação, permitindo a remoção de mais um dos piores colocados. A visualização mostra um deslocamento muito mais ativo dos indivíduos da população no espaço de soluções. No entanto, surgiu um novo problema: observou-se uma grande dispersão nos resultados, e não foi possível eliminar totalmente a estagnação em ótimos locais.

      Hilly

      ATAm na função de teste Hilly

      Forest

      ATAm na função de teste Forest

      Megacity

      ATAm na função de teste Megacity

      O algoritmo de tribo artificial conquistou o 33º lugar na tabela de classificação.

      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 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
      7 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
      8 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
      9 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
      10 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
      11 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
      12 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
      13 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
      14 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
      –15 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
      16 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
      17 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
      18 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
      19 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
      20 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
      21 (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
      22 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
      23 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
      24 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
      25 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
      26 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
      27 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
      28 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
      29 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
      30 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
      31 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
      32 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
      33 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
      34 ASHA artificial showering algorithm 0,89686 0,40433 0,25617 1,55737 0,80360 0,35526 0,19160 1,35046 0,47692 0,18123 0,09774 0,75589 3,664 40,71
      35 ASBO adaptive social behavior optimization 0,76331 0,49253 0,32619 1,58202 0,79546 0,40035 0,26097 1,45677 0,26462 0,17169 0,18200 0,61831 3,657 40,63
      36 MEC mind evolutionary computation 0,69533 0,53376 0,32661 1,55569 0,72464 0,33036 0,07198 1,12698 0,52500 0,22000 0,04198 0,78698 3,470 38,55
      37 IWO invasive weed optimization 0,72679 0,52256 0,33123 1,58058 0,70756 0,33955 0,07484 1,12196 0,42333 0,23067 0,04617 0,70017 3,403 37,81
      38 Micro-AIS micro artificial immune system 0,79547 0,51922 0,30861 1,62330 0,72956 0,36879 0,09398 1,19233 0,37667 0,15867 0,02802 0,56335 3,379 37,54
      39 COAm cuckoo optimization algorithm M 0,75820 0,48652 0,31369 1,55841 0,74054 0,28051 0,05599 1,07704 0,50500 0,17467 0,03380 0,71347 3,349 37,21
      40 SDOm spiral dynamics optimization M 0,74601 0,44623 0,29687 1,48912 0,70204 0,34678 0,10944 1,15826 0,42833 0,16767 0,03663 0,63263 3,280 36,44
      41 NMm Nelder-Mead method M 0,73807 0,50598 0,31342 1,55747 0,63674 0,28302 0,08221 1,00197 0,44667 0,18667 0,04028 0,67362 3,233 35,92
      42 FAm firefly algorithm M 0,58634 0,47228 0,32276 1,38138 0,68467 0,37439 0,10908 1,16814 0,28667 0,16467 0,04722 0,49855 3,048 33,87
      43 GSA gravitational search algorithm 0,64757 0,49197 0,30062 1,44016 0,53962 0,36353 0,09945 1,00260 0,32667 0,12200 0,01917 0,46783 2,911 32,34
      44 BFO bacterial foraging optimization 0,61171 0,43270 0,31318 1,35759 0,54410 0,21511 0,05676 0,81597 0,42167 0,13800 0,03195 0,59162 2,765 30,72
      45 ABC artificial bee colony 0,63377 0,42402 0,30892 1,36671 0,55103 0,21874 0,05623 0,82600 0,34000 0,14200 0,03102 0,51302 2,706 30,06



      Considerações finais

      Neste artigo, examinamos em detalhes um dos algoritmos de otimização mais modernos — o algoritmo ATA. Apesar de este algoritmo não apresentar resultados excepcionais quando comparado a outros métodos, sua importância reside no fato de que ele traz uma contribuição valiosa para nossa compreensão do gerenciamento dinâmico do estado populacional e das estratégias de análise dos problemas relacionados à estagnação em ótimos locais.

      O interesse pelo algoritmo ATA não se limita às suas duas fases principais, que por si só têm valor limitado como métodos de busca de soluções. O aspecto mais relevante é a abordagem que emprega a escolha dinâmica das fases de movimentação dos indivíduos e o controle do estado da população. É justamente esse ponto que permite adaptar o algoritmo de forma mais eficaz às condições variáveis do problema e melhorar a qualidade das soluções obtidas. Assim, o estudo do ATA abre novos horizontes para futuras pesquisas na área de otimização algorítmica e pode servir de base para o desenvolvimento de métodos mais avançados.

      Também estou certo de que diversos operadores podem ser aplicados ao algoritmo discutido, o que aumentaria significativamente sua eficácia. Por exemplo, o uso de operadores de seleção baseados em ordenação ou cruzamento pode melhorar bastante os resultados.

      No entanto, vale destacar que a versão atual do algoritmo não possui dependência da qualidade da solução, e também carece de propriedades combinatórias, o que limita seu potencial. Todos esses pontos representam direções interessantes para futuras pesquisas e melhorias, embora estejam além do escopo deste artigo. Ficaria muito feliz se algum dos leitores decidisse experimentar as modificações sugeridas e compartilhasse suas versões do algoritmo nos comentários.

      Tab

      Figura 3. Graduação de cores dos algoritmos conforme os testes correspondentes. Branco destaca resultados maiores ou iguais a 0.99

      chart

      Figura 4. Histograma dos resultados de testes dos algoritmos (em uma escala de 0 a 100, quanto maior, melhor, onde 100 é o resultado teórico máximo possível, no arquivo compactado há um script para cálculo da tabela comparativa)

      Vantagens e desvantagens do algoritmo ATAm:

      Vantagens:

      1. Poucos parâmetros externos.
      2. Implementação simples.
      3. Ideia interessante de troca dinâmica entre estratégias de busca.

      Desvantagens:

      1. Alta variabilidade nos resultados.
      2. Baixa precisão na convergência.
      3. Tendência a estagnar.

      Está anexado ao artigo um arquivo compactado com as versões atualizadas dos códigos dos algoritmos. 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 a capacidade de busca. As conclusões e interpretações apresentadas nos artigos são baseadas nos resultados dos experimentos realizados.

      Programas utilizados no artigo

      # Nome Tipo Descrição
      1 #C_AO.mqh
      Arquivo incluído
      Classe pai dos algoritmos populacionais de otimização
      2 #C_AO_enum.mqh
      Arquivo incluído
      Enumeração dos algoritmos populacionais de otimização
      3 TestFunctions.mqh
      Arquivo incluído
      Biblioteca de funções de teste
      4
      TestStandFunctions.mqh
      Arquivo incluído
      Biblioteca de funções da bancada de testes
      5
      Utilities.mqh
      Arquivo incluído
      Biblioteca de funções auxiliares
      6
      CalculationTestResults.mqh
      Arquivo incluído
      Script para cálculo dos resultados na tabela comparativa
      7
      Testing AOs.mq5
      Script Bancada de testes unificada 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_ATAm.mq5
      Script Bancada de testes para o ATAm

      Traduzido do russo pela MetaQuotes Ltd.
      Artigo original: https://www.mql5.com/ru/articles/16588

      Arquivos anexados |
      ATAm.ZIP (143.44 KB)
      Robô de trading multimódulo em Python e MQL5 (Parte I): Criando a arquitetura básica e os primeiros módulos Robô de trading multimódulo em Python e MQL5 (Parte I): Criando a arquitetura básica e os primeiros módulos
      Estamos desenvolvendo um sistema de trading modular que combina Python para análise de dados com MQL5 para execução de ordens. Quatro módulos independentes monitoram paralelamente diferentes aspectos do mercado: volumes, arbitragem, economia e riscos, utilizando RandomForest com 400 árvores para análise. É dado um foco especial no gerenciamento de risco, pois sem uma gestão adequada, até os algoritmos de trading mais avançados tornam-se inúteis.
      Redes neurais em trading: Framework híbrido de negociação com codificação preditiva (StockFormer) Redes neurais em trading: Framework híbrido de negociação com codificação preditiva (StockFormer)
      Apresentamos o sistema de negociação híbrido StockFormer, que combina codificação preditiva e algoritmos de aprendizado por reforço (RL). O framework utiliza 3 ramos Transformer com mecanismo integrado Diversified Multi-Head Attention (DMH-Attn), que melhora o módulo de atenção padrão com um bloco Feed-Forward multicabeça, permitindo capturar padrões de séries temporais em diferentes subespaços.
      Do básico ao intermediário: Objetos (I) Do básico ao intermediário: Objetos (I)
      Neste artigo, começarmos a ver como poderemos trabalhar com objetos diretamente no gráfico. Isto utilizando um código construído especialmente para apresentar algo a nós. Trabalhar com objetos é algo muito interessante e bastante divertido. Como este será o primeiro contato. Iremos começar com algo bem simples.
      EA baseado em um aproximador universal MLP EA baseado em um aproximador universal MLP
      Este artigo apresenta uma forma simples e acessível de usar uma rede neural em um EA, que não exige conhecimento aprofundado em aprendizado de máquina. O método elimina a necessidade de normalizar a função alvo e evita problemas como “explosão de pesos” e “paralisação da rede”, oferecendo um aprendizado intuitivo com controle visual dos resultados.