English Русский 中文 Español Deutsch 日本語
preview
Colmeia artificial de abelhas — Artificial Bee Hive Algorithm (ABHA): Teoria e métodos

Colmeia artificial de abelhas — Artificial Bee Hive Algorithm (ABHA): Teoria e métodos

MetaTrader 5Exemplos |
236 0
Andrey Dik
Andrey Dik
Conteúdo:
  1. Introdução
  2. Implementação do algoritmo
  3. Considerações finais


1. Introdução

Em um dos artigos anteriores, analisamos o algoritmo da Colônia de Abelhas (ABC), que é um excelente exemplo de como a natureza inspira a criação de métodos computacionais eficientes. Uma colônia de abelhas não é apenas um grupo de insetos, mas um sistema altamente organizado, onde cada abelha tem seu papel específico. Algumas abelhas são exploradoras, investigando os arredores em busca de alimento, enquanto outras assumem o papel de coletoras, que recolhem néctar e pólen. Essa forma de cooperação permite que a colônia seja mais eficiente na busca por recursos do que seria se cada abelha agisse de forma isolada.

O novo algoritmo de colmeia artificial, apresentado neste artigo, explora mais profundamente e de forma mais abrangente o processo de busca por alimentos realizado por esses insetos, demonstrando como a interação coletiva e a divisão de papéis promovem a descoberta de novas fontes de alimento. Ele mostra como a interação entre os agentes pode levar a resultados mais eficazes. Esse algoritmo analisa detalhadamente os papéis específicos de cada indivíduo na colônia de abelhas.

O principal objetivo do ABHA é encontrar soluções ótimas em espaços multidimensionais, nos quais funções podem apresentar diversos mínimos e máximos locais. Isso torna o problema de otimização especialmente desafiador, pois os métodos tradicionais podem ficar presos em extremos locais, sem alcançar o ótimo global. O algoritmo ABHA se inspira nas estratégias de busca por alimento utilizadas pelas abelhas. Na natureza, as abelhas empregam métodos coletivos que lhes permitem encontrar fontes de néctar de maneira eficiente, e esse princípio foi adaptado para criar um algoritmo que aprimora o processo de busca por soluções ótimas.

Na estrutura do ABHA, estão previstos vários estados que refletem a dinâmica do comportamento delas. Um desses estados é o "estado experiente", no qual as abelhas compartilham informações sobre as fontes de alimento encontradas. Esse estado contribui para o acúmulo de conhecimento sobre as áreas mais produtivas do espaço multidimensional. Outro estado importante é o "estado de busca", no qual as abelhas exploram ativamente o espaço em busca das melhores fontes, utilizando as informações obtidas de suas companheiras.

Desenvolvido em 2009 por um grupo de pesquisadores liderado por André Muñoz, o Algoritmo do Enxame Artificial de Abelhas (Artificial Beehive Algorithm, ABHA) tem como objetivo resolver problemas de otimização contínua.


2. Implementação do algoritmo

O ABHA é um método interessante que utiliza uma analogia com o comportamento das abelhas para resolver problemas complexos de otimização em espaços de busca contínuos. Vamos revisar os conceitos básicos do algoritmo:

1. Modelagem do comportamento das abelhas:

  • O ABHA é baseado em um modelo de comportamento individual das abelhas. Cada agente (abelha) no algoritmo segue um conjunto de regras comportamentais para determinar as ações que deve realizar.

2. Interações dentro da colmeia:

  • O foco principal do ABHA está na interação entre as abelhas.
  • Elas trocam informações sobre as soluções encontradas.

O algoritmo utiliza quatro estados (ou papéis) das abelhas, que podem ser interpretados como diferentes tipos de comportamento. Esses estados são apresentados na seguinte tabela:
Estado da abelha
Tipos de comportamento
Novato (Novice state)
Permanece na "enxame" (posição abstrata em que ocorre o intercâmbio de informações) e não possui informações sobre fontes de alimento.
Experiente (Experimented state)   Possui informações sobre uma fonte de alimento e pode compartilhá-las.
Explorador (Search state)  Busca uma fonte de alimento melhor do que a atual.
Explorador Intensivo (Food source state) Avalia a rentabilidade da sua fonte de alimento e decide se deve divulgá-la.

Cada um desses estados reflete um aspecto diferente do comportamento das abelhas na busca e exploração de fontes de alimento. Cada estado implica um conjunto de regras que a abelha correspondente deve seguir:

Estado da abelha   Regras de mudança de posição da abelha no espaço
Novato
Caso as informações sobre a fonte de alimento não estejam disponíveis, a abelha pode iniciar uma busca aleatória ou seguir uma "dança". Se as informações sobre a fonte de alimento não estiverem disponíveis, ela pode iniciar uma busca aleatória.
Experiente Se as informações sobre a fonte de alimento forem válidas, a abelha pode transmiti-las para outras abelhas por meio de uma "dança". Se as informações forem inválidas, ela pode iniciar uma busca aleatória.
Explorador A abelha altera sua posição usando informações sobre a direção e o tamanho do passo, até encontrar uma fonte de alimento melhor.
Explorador Intensivo A abelha avalia a rentabilidade da fonte e, se esta não atender aos critérios, pode mudar a direção da busca.

Nem todas as abelhas podem compartilhar informações sobre fontes de alimento, nem todas podem receber informações de outras abelhas que têm essa capacidade. Existem dois tipos de abelhas que têm o direito de receber ou transmitir informações sobre fontes de alimento:

1. Possuem a capacidade de transmitir informações:

  • Experiente: pode compartilhar informações com outras abelhas por meio de uma "dança", caso as informações sobre a fonte de alimento sejam válidas.

2. Possuem a capacidade de receber informações por meio da dança de outras abelhas:

  • Novato: pode seguir a "dança", se disponível, para obter informações sobre fontes de alimento.
  • Experiente: pode receber informações por meio da dança de outras abelhas e acessar dados sobre fontes de alimento.

As abelhas podem mudar de estado dependendo das condições relacionadas à sua experiência e às informações sobre fontes de alimento. Abaixo estão listados os tipos de abelhas e as condições em que podem transitar de um estado para outro:

1. Novato

  • Para experiente. Se o novato obtiver informações sobre uma fonte de alimento altamente lucrativa (por exemplo, por meio da dança de outras abelhas), ele pode mudar para o estado de experiente.
  • Para explorador. Se o novato não receber informações sobre fontes de alimento, ele pode começar a procurar por conta própria e mudar para o estado de explorador.

2. Experiente

  • Para explorador. Se as informações sobre a fonte de alimento atual se mostrarem insuficientes (por exemplo, o valor atual de adaptabilidade estiver abaixo do limite), a abelha pode mudar para o estado de explorador em busca de novas fontes.
  • Para explorador intensivo. Se as informações sobre a fonte de alimento forem confirmadas (por exemplo, o valor atual de adaptabilidade é alto e estável), a abelha pode mudar para o estado de explorador intensivo para uma análise mais aprofundada da fonte.

3. Explorador

  • Para explorador intensivo. Se o explorador encontrar uma fonte de alimento com boas características (por exemplo, o valor atual de adaptabilidade está acima do limite), ele pode mudar para o estado de explorador intensivo para avaliar periodicamente sua rentabilidade.
  • Para novatos. Se o explorador não encontrar nenhuma fonte de alimento ou se as informações se mostrarem insuficientes, ele pode retornar ao estado de novato.

4. Explorador Intensivo

  • Para explorador. Se a fonte de alimento atual se mostrar não lucrativa (por exemplo, o valor atual de adaptabilidade está abaixo do limite), a abelha pode mudar para o estado de explorador para buscar novas fontes.
  • Para experiente. Se o explorador intensivo encontrar uma fonte de alimento que confirme sua rentabilidade, ele pode mudar para o estado de experiente para compartilhar as informações com outras abelhas.

Essas transições entre estados permitem que o algoritmo ajuste dinamicamente sua estratégia de busca, dependendo da posição dos indivíduos no espaço de soluções, além de promover um intercâmbio eficiente de informações sobre as fontes de alimento.

Um conceito fundamental no algoritmo é o de "fonte de alimento" e a "dança das abelhas". No contexto do algoritmo, uma "fonte de alimento" representa uma possível solução para o problema de otimização:

1. Cada "fonte de alimento" corresponde a uma posição específica, que representa uma solução possível para o problema de otimização do espaço de busca. 
2. A qualidade ou "rentabilidade" de uma fonte de alimento é determinada pelo valor da função objetivo naquele ponto. Quanto maior o valor da função objetivo, mais "rentável" será a fonte de alimento.
3. No algoritmo, as abelhas buscam e exploram as fontes de alimento mais "rentáveis", ou seja, aquelas posições que correspondem aos melhores valores da função objetivo.
4. O esgotamento de uma fonte de alimento indica que não é mais possível encontrar uma solução melhor naquele ponto do espaço de busca. Nesse caso, as abelhas devem mudar para buscar novas áreas mais promissoras.

No algoritmo, a "dança" é a forma como as abelhas trocam informações sobre as "fontes de alimento" encontradas. Essa troca funciona da seguinte maneira:

  • Quando uma abelha encontra uma "fonte de alimento" promissora, ela retorna ao "enxame" e realiza uma "dança".
  • A duração da "dança" depende da "rentabilidade" da fonte de alimento encontrada — quanto melhor a solução, mais longa será a "dança".
  • Outras abelhas no enxame podem observar essa "dança" e, assim, obter informações sobre a fonte de alimento. A probabilidade de uma abelha seguir a "dança" depende da "rentabilidade" da fonte de alimento.

Assim, no algoritmo ABHA, uma "fonte de alimento" é o equivalente a uma solução potencial para o problema de otimização, e sua "rentabilidade" é determinada pelo valor da função objetivo na posição correspondente no espaço de busca. A "dança" funciona como um mecanismo de transmissão de informações entre as abelhas sobre as soluções mais promissoras descobertas durante o processo de busca.

No algoritmo ABHA, cada tipo de abelha utiliza os valores de adaptabilidade (ou custo) do passo anterior, do passo atual e o melhor valor de adaptabilidade da seguinte forma:

Estado da abelha 
Novato
Experiente
Explorador
Explorador Intensivo
Valor atual
Usado para transitar para o estado de Experiente ou Explorador.
Se o valor atual for alto e as informações forem válidas, a abelha pode compartilhá-las com outras por meio da dança.
A abelha usa o valor atual de adaptabilidade para avaliar sua posição atual e decidir se deve continuar buscando ou mudar de direção.
Se o valor atual estiver abaixo do limite, você pode decidir que a fonte não é suficientemente boa e iniciar a busca por uma nova.
Valor anterior
Não usado
A abelha compara o valor atual com o anterior para determinar se houve melhora. Se o valor atual for melhor, a probabilidade de compartilhar as informações aumenta.
A abelha compara o valor atual com o anterior para avaliar se sua posição melhorou. Se o valor atual for melhor, ela pode continuar na mesma direção.
Não usado
Melhor valor
Não usado
A abelha pode usar o melhor valor para avaliar se vale a pena continuar investigando a fonte atual ou buscar uma nova.
A abelha usa o melhor valor para determinar se a fonte atual é mais vantajosa do que a anterior. Isso ajuda a decidir se deve permanecer no local ou continuar buscando.
A abelha usa o melhor valor para decidir se deve continuar explorando a fonte atual ou transitar para o estado de Experiente.

Cada tipo de abelha utiliza as informações de adaptabilidade em diferentes iterações para tomar decisões e transitar entre estados.

No algoritmo, as probabilidades de escolha de ações, como a probabilidade de busca aleatória, de seguir uma dança ou de abandonar uma fonte (ou permanecer próxima a ela), são calculadas dinamicamente ao longo de todo o processo de otimização. Essas probabilidades ajudam os agentes (abelhas) a tomar decisões sobre como agir, com base nas informações disponíveis e no estado do ambiente.

Cálculo das probabilidades:

1. Probabilidade de busca aleatória (Psrs): Refere-se à probabilidade de a abelha iniciar uma busca aleatória em vez de seguir a dança ou permanecer na fonte atual.

      2. Probabilidade de seguir a dança (Prul): Indica a probabilidade de uma abelha seguir a dança de outra abelha.

          3. Probabilidade de abandonar a fonte (Pab): Refere-se à probabilidade de a abelha permanecer na fonte atual ou abandoná-la.

              As abelhas, em diferentes estados, utilizam essas probabilidades de formas distintas, e as probabilidades variam para cada estado.

              1.  Novato:

              • Psrs: Alta, já que a abelha não possui informações sobre outras fontes e pode iniciar uma busca aleatória.
              • Prul: Pode ser usada se outras abelhas estiverem dançando, mas a probabilidade dependerá das informações disponíveis.
              • Pab: Não se aplica, pois a abelha ainda não encontrou uma fonte de alimento.

              2. Experiente:

              • Psrs: Baixa, pois a abelha já possui informações sobre a fonte.
              • Prul: Usada para transmitir informações a outras abelhas, se a informação sobre a fonte for considerada válida.
              • Pab: Pode ser usada para decidir se vale a pena continuar explorando a fonte atual ou abandoná-la, caso sua rentabilidade seja baixa.

               3. Explorador:

              • Psrs: Pode ser usada se a abelha não encontrar fontes satisfatórias.
              • Prul: Pode ser usada se a abelha decidir seguir a dança de outra abelha para encontrar uma nova fonte.
              • Pab: Aplicada para avaliar se vale a pena continuar a busca ou retornar ao "ninho".

               4. Explorador Intensivo:

              • Psrs: Baixa, pois a abelha já encontrou uma fonte.
              • Prul: Usada para transmitir informações sobre uma fonte válida a outras abelhas, se a fonte for considerada rentável.
              • Pab: Alta, se a fonte não trouxer resultados satisfatórios, o que pode levar à decisão de abandoná-la.

              Espero que tenhamos abrangido todas as nuances do comportamento das abelhas e possamos agora prosseguir com a construção do pseudocódigo.

              Inicialização:
                  Definir os parâmetros do algoritmo (popSize, maxSearchAttempts, abandonmentRate, etc.)
                  Criar uma população de agentes com popSize em posições aleatórias
                  Definir o estado inicial de cada agente como "Novato"

              Ciclo principal:
                  Enquanto a condição de parada não for atingida:
                      Para cada agente:
                          Executar uma ação com base no estado atual:
                              "Novato": busca aleatória ou seguir a dança
                              "Experiente": busca aleatória, seguir a dança ou busca local
                              "Explorador": movimento na direção especificada
                              "Explorador Intensivo": busca local ao redor da melhor posição
                          
                          Avaliar a fitness do agente
                          Atualizar a melhor solução global, caso encontrada

                      Calcular probabilidades e custo médio das soluções

                      Para cada agente:
                          Atualizar estado:
                              "Novato": transitar para "Experiente" ou "Explorador"
                              "Experiente": possível transição para "Explorador Intensivo" ou "Explorador"
                              "Explorador": possível transição para "Novato" ou "Explorador Intensivo"
                              "Explorador Intensivo": possível transição para "Explorador" ou "Experiente"

                          Atualizar a melhor posição pessoal e custo

                  Calcular as probabilidades para os agentes
                  Calcular o custo médio

              Agora, passamos para a escrita do código do algoritmo. A lógica do ABHA é bastante complexa e o código é extenso, portanto descreveremos detalhadamente a estrutura, as classes e os métodos utilizados na implementação.

              A estrutura S_ABHA_Agent representa o agente "abelha" no algoritmo inspirado pelo comportamento das abelhas. Descrição da estrutura:

              1. Enumeração BeeState define os diferentes estados da abelha:

              • stateNovice: estado de novato, quando a abelha está começando sua atividade.
              • stateExperienced: estado de abelha experiente, que já possui alguma experiência.
              • stateSearch: estado de busca, quando a abelha está ativamente procurando fontes de alimento.
              • stateSource: estado em que a abelha permanece próxima a uma fonte e realiza avaliações periódicas.

              2. Campos da estrutura:

              • position[]: array contendo a posição atual da abelha no espaço de busca.
              • bestPosition[]: array contendo a melhor posição encontrada pela abelha.
              • direction[]: array do vetor de direção do movimento da abelha.
              • cost: valor que indica a qualidade da fonte de alimento atual.
              • prevCost: valor que indica a qualidade da fonte de alimento anterior.
              • bestCost: valor que indica a qualidade da melhor fonte de alimento encontrada.
              • stepSize: coeficiente que define o tamanho do passo da abelha ao se mover pelas coordenadas.
              • state: estado atual da abelha, representado como um número inteiro.
              • searchCounter: contador que acompanha as ações da abelha no estado de busca.

              3. Campos da estrutura que definem probabilidades:

              • pab: probabilidade de permanecer na fonte de alimento.
              • p_si: probabilidade dinâmica de outras abelhas escolherem seguir a dança desta abelha.
              • p_srs: probabilidade de realizar uma busca aleatória.
              • p_rul: probabilidade de seguir a dança de outra abelha.
              • p_ab: probabilidade de permanecer próxima à fonte de alimento.

              4. Método Init:

              • Inicializa o agente, recebendo como entrada o número de coordenadas (coords) e o tamanho inicial do passo (initStepSize).
              • O método aloca memória para os arrays, define os valores iniciais de todos os membros da estrutura, incluindo estado, contadores e probabilidades.

              A estrutura S_ABHA_Agent é usada para modelar o comportamento das abelhas no algoritmo, permitindo que elas alterem entre estados, explorem o espaço em busca de alimento e interajam entre si. A inicialização da estrutura configura os parâmetros iniciais necessários para o funcionamento do algoritmo.

              //——————————————————————————————————————————————————————————————————————————————
              struct S_ABHA_Agent
              {
                  enum BeeState
                  {
                    stateNovice      = 0,    // Novice state
                    stateExperienced = 1,    // Experienced state
                    stateSearch      = 2,    // Search state
                    stateSource      = 3     // Food source state
                  };
              
                  double position        []; // Current position of the bee
                  double bestPosition    []; // Best bee position found
                  double direction       []; // Bee movement direction vector
                  double cost;               // Current food source quality
                  double prevCost;           // Previous food source quality
                  double bestCost;           // Best food source found quality
                  double stepSize;           // Step ratio in all coordinates during a bee movement
                  int    state;              // Bee's current state
                  int    searchCounter;      // Counter of the bee actions in the search state
              
                  double pab;                // Probability of remaining near the source
                  double p_si;               // Dynamic probability of other bees choosing this bee's dance
              
                  double p_srs;              // Random search probability
                  double p_rul;              // Probability of following the dance
                  double p_ab;               // Probability of source rejection
              
                  void Init (int coords, double initStepSize)
                  {
                    ArrayResize (position,        coords);
                    ArrayResize (bestPosition,    coords);
                    ArrayResize (direction,       coords);
                    cost              = -DBL_MAX;
                    prevCost          = -DBL_MAX;
                    bestCost          = -DBL_MAX;
                    state             = stateNovice;
                    searchCounter     = 0;
                    pab               = 0;
                    p_si              = 0;
                    p_srs             = 0;
                    p_rul             = 0;
                    p_ab              = 0;
              
                    stepSize        = initStepSize;
                  }
              };
              //——————————————————————————————————————————————————————————————————————————————
              

              A classe C_AO_ABHA herda da classe base C_AO, o que implica que ela utiliza funcionalidades definidas na classe pai. Descrição da classe:

              1. Construtor C_AO_ABHA():

              • Define parâmetros como o tamanho da população (popSize), o número máximo de tentativas de busca (maxSearchAttempts), coeficientes para diferentes probabilidades e o tamanho inicial do passo (initialStepSize).
              • Inicializa o array params, que contém os parâmetros do algoritmo.

              2. O método SetParams() define os valores dos parâmetros do algoritmo com base nos valores armazenados no array params.

              3. O método Init() inicializa o algoritmo, recebendo como entrada os valores mínimos e máximos do intervalo de busca, o passo de busca e o número de épocas. 

              4. Os métodos Moving() e Revision() são responsáveis por executar a lógica de movimento dos agentes (abelhas) e revisar as soluções encontradas.

              5. Membros da classe:

              • maxSearchAttempts: número máximo de tentativas de busca.
              • abandonmentRate: taxa de mudança na probabilidade de permanecer na fonte de alimento.
              • randomSearchProbability: probabilidade de realizar uma busca aleatória.
              • stepSizeReductionFactor: coeficiente de redução do tamanho do passo.
              • initialStepSize: tamanho inicial do passo.
              • S_ABHA_Agent agents[]: array de agentes (abelhas) que participam do algoritmo.
              • avgCost: custo médio das soluções encontradas.

              6. Métodos para ações das abelhas:

              • ActionRandomSearch(): realiza busca aleatória dentro de um intervalo especificado.
              • ActionFollowingDance(): segue a dança de outra abelha.
              • ActionMovingDirection(): realiza movimento em uma direção especificada considerando o tamanho do passo.
              • ActionHiveVicinity(): movimenta-se nas proximidades da fonte de alimento.

              7. Métodos para atividades das abelhas em diferentes estados: StageActivityNovice(), StageActivityExperienced(), StageActivitySearch(), StageActivitySource(): definem as ações das abelhas dependendo de seus estados.

              8. Métodos para transição de estados das abelhas: ChangingStateForNovice(), ChangingStateForExperienced(), ChangingStateForSearch(), ChangingStateForSource(): alteram os estados das abelhas com base em suas atividades.

              9. Métodos para cálculos:

              • CalculateProbabilities(): calcula as probabilidades para as ações das abelhas.
              • CalculateAverageCost(): calcula o custo médio das soluções encontradas.

              A classe C_AO_ABHA implementa um algoritmo de otimização inspirado no comportamento das abelhas e cobre vários aspectos do trabalho das abelhas, como movimento, tomada de decisões e transição de estados.

              //——————————————————————————————————————————————————————————————————————————————
              class C_AO_ABHA : public C_AO
              {
                public:
                C_AO_ABHA ()
                {
                  ao_name = "ABHA";
                  ao_desc = "Artificial Bee Hive Algorithm";
                  ao_link = "https://www.mql5.com/en/articles/15347";
              
                  popSize                 = 10;
              
                  maxSearchAttempts       = 10;
                  abandonmentRate         = 0.1;
                  randomSearchProbability = 0.1;
                  stepSizeReductionFactor = 0.99;
                  initialStepSize         = 0.5;
              
                  ArrayResize (params, 6);
                  params [0].name = "popSize";                 params [0].val = popSize;
              
                  params [1].name = "maxSearchAttempts";       params [1].val = maxSearchAttempts;
                  params [2].name = "abandonmentRate";         params [2].val = abandonmentRate;
                  params [3].name = "randomSearchProbability"; params [3].val = randomSearchProbability;
                  params [4].name = "stepSizeReductionFactor"; params [4].val = stepSizeReductionFactor;
                  params [5].name = "initialStepSize";         params [5].val = initialStepSize;
                }
              
                void SetParams ()
                {
                  popSize                 = (int)params [0].val;
              
                  maxSearchAttempts       = (int)params [1].val;
                  abandonmentRate         = params      [2].val;
                  randomSearchProbability = params      [3].val;
                  stepSizeReductionFactor = params      [4].val;
                  initialStepSize         = params      [5].val;
                }
              
                bool Init (const double &rangeMinP  [], //minimum search range
                           const double &rangeMaxP  [], //maximum search range
                           const double &rangeStepP [], //step search
                           const int     epochsP = 0);  //number of epochs
              
                void Moving   ();
                void Revision ();
              
                //----------------------------------------------------------------------------
                int    maxSearchAttempts;
                double abandonmentRate;
                double randomSearchProbability;
                double stepSizeReductionFactor;
                double initialStepSize;
              
                S_ABHA_Agent agents [];
              
                private: //-------------------------------------------------------------------
                double avgCost;
              
                //Types of bees' actions----------------------------------------------------------
                double ActionRandomSearch       (int coordInd);                      //1. Random search (random placement in a range of coordinates)
                double ActionFollowingDance     (int coordInd, double val);          //2. Follow the dance (move in the direction of the dancer)
                double ActionMovingDirection    (S_ABHA_Agent &agent, int coordInd); //3. Move in a given direction with a step
                double ActionHiveVicinity       (int coordInd, double val);          //4. Move in the vicinity of a food source
              
                //Actions of bees in different states----------------------------------------
                void   StageActivityNovice      (S_ABHA_Agent &agent); //actions 1 or 2
                void   StageActivityExperienced (S_ABHA_Agent &agent); //actions 1 or 2 or 4
                void   StageActivitySearch      (S_ABHA_Agent &agent); //actions 3
                void   StageActivitySource      (S_ABHA_Agent &agent); //actions 4
              
                //Change bees' state----------------------------------------------------
                void ChangingStateForNovice      (S_ABHA_Agent &agent);
                void ChangingStateForExperienced (S_ABHA_Agent &agent);
                void ChangingStateForSearch      (S_ABHA_Agent &agent);
                void ChangingStateForSource      (S_ABHA_Agent &agent);
              
                void CalculateProbabilities ();
                void CalculateAverageCost   ();
              };
              //——————————————————————————————————————————————————————————————————————————————
              

              O método Init da classe C_AO_ABHA é responsável por inicializar o algoritmo ABHA. Vamos detalhá-lo:

              1. Parâmetros do método:

              • rangeMinP[]: array de valores mínimos do intervalo de busca, representando os limites inferiores de cada variável a ser otimizada.
              • rangeMaxP[]: array de valores máximos do intervalo de busca, representando os limites superiores de cada variável.
              • rangeStepP[]: array de valores de passo de busca, determinando o quanto as variáveis são alteradas durante o processo de busca.
              • epochsP: número de épocas (iterações) durante as quais o algoritmo será executado. 

              2. O método retorna "true" se a inicialização for bem-sucedida e "false" se ocorrer um erro.

              Lógica do método:

              • A chamada ao método StandardInit com os parâmetros do intervalo de busca executa operações padrão de inicialização, como a configuração dos limites de busca e dos passos. Se a inicialização falhar, o método Init é encerrado e retorna false.
              • O método ArrayResize ajusta o tamanho do array agents, que representa as abelhas (agentes) no algoritmo. O tamanho do array é definido por popSize, que determina o número de agentes participantes da otimização.
              • Um laço inicializa cada agente no array agents. Para cada agente, o método Init é chamado, configurando suas coordenadas iniciais (a partir do array coords) e o tamanho inicial do passo inicial (a partir do array steps). Esse passo define a distância máxima que o agente pode se mover durante o processo de busca.

              O método Init da classe C_AO_ABHA realiza as seguintes tarefas:

              • Verifica se a inicialização padrão dos parâmetros de busca foi bem-sucedida.
              • Ajusta o tamanho do array de agentes de acordo com o número especificado de abelhas.
              • Inicializa cada agente por meio de seu método Init, configurando os parâmetros iniciais necessários para o funcionamento do algoritmo.

              Se todas as etapas forem realizadas com sucesso, o método retorna "true", indicando que a inicialização do algoritmo foi concluída com êxito.

              //——————————————————————————————————————————————————————————————————————————————
              bool C_AO_ABHA::Init (const double &rangeMinP  [], //minimum search range
                                    const double &rangeMaxP  [], //maximum search range
                                    const double &rangeStepP [], //step search
                                    const int     epochsP = 0)   //number of epochs
              {
                if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;
              
                ArrayResize (agents, popSize);
                for (int i = 0; i < popSize; i++)
                {
                  agents [i].Init (coords, initialStepSize);
                }
                return true;
              }
              //————————————————————
              

              A seguir, analisaremos o método Moving da classe C_AO_ABHA, que implementa a etapa de movimentação dos agentes no algoritmo. O método Moving não recebe parâmetros nem retorna valores. Ele gerencia o movimento dos agentes (abelhas) durante o processo de otimização. Lógica do método:

              1. Inicialização inicial.

              • Verificação da variável revision: se for "false", significa que este é o primeiro chamado do método, e as posições dos agentes precisam ser inicializadas.
              • Geração de posições iniciais: laços aninhados percorrem todos os agentes e suas coordenadas. Para cada coordenada:
                • Um valor aleatório val é gerado dentro do intervalo especificado (rangeMin e rangeMax).
                • Esse valor é então ajustado usando o método SeInDiSp, que assegura que o valor esteja dentro do intervalo permitido com o passo definido.
                • As posições atuais e as melhores posições do agente são configuradas como iguais no início.
                • Uma direção de movimento aleatória para o agente é gerada.
              • Após a inicialização, a variável revision é definida como "true", e o método é concluído.

              2. Lógica principal de movimentação dos agentes. Movimentação de agentes entre estados:

              • Para cada agente, seu estado atual (novato, experiente, explorador ou explorador intensivo) é determinado usando um "switch". Dependendo do estado, o método correspondente é chamado para gerenciar o comportamento do agente (como StageActivityNovice, StageActivityExperienced, etc.).
              • Após a execução das ações baseadas no estado, as posições dos agentes são atualizadas usando o método SeInDiSp para garantir que permaneçam dentro dos limites permitidos.

              3. O laço atualiza o array a, copiando as posições atuais dos agentes nos elementos correspondentes do array a.

              No algoritmo ABHA, o papel do método Moving é gerenciar o movimento dos agentes. Inicialmente, ele define as posições dos agentes quando o método é chamado pela primeira vez. Em seguida, ele atualiza as posições com base nos estados dos agentes. Este método inclui:

              • Geração de posições iniciais aleatórias.
              • Determinação do comportamento dos agentes com base em seus estados.
              • Atualização das posições atuais dos agentes no array a

              Este método é fundamental para chamar os demais métodos relacionados aos estados das abelhas, garantindo o comportamento dinâmico dos agentes durante o processo de otimização.

              //——————————————————————————————————————————————————————————————————————————————
              void C_AO_ABHA::Moving ()
              {
                //----------------------------------------------------------------------------
                if (!revision)
                {
                  double val = 0.0;
              
                  for (int i = 0; i < popSize; i++)
                  {
                    for (int c = 0; c < coords; c++)
                    {
                      val = u.RNDfromCI (rangeMin [c], rangeMax [c]);
                      val = u.SeInDiSp (val, rangeMin [c], rangeMax [c], rangeStep [c]);
              
                      agents [i].position     [c] = val;
                      agents [i].bestPosition [c] = val;
                      agents [i].direction    [c] = u.RNDfromCI (-(rangeMax [c] - rangeMin [c]), (rangeMax [c] - rangeMin [c]));
              
                      a [i].c [c] = val;
                    }
                  }
                  revision = true;
                  return;
                }
                //----------------------------------------------------------------------------
                for (int i = 0; i < popSize; i++)
                {
                  switch (agents [i].state)
                  {
                    //------------------------------------------------------------------------
                    //Novice
                    case S_ABHA_Agent::stateNovice:
                    {
                      StageActivityNovice (agents [i]);
                      break;
                    }
                      //------------------------------------------------------------------------
                      //Experienced
                    case S_ABHA_Agent::stateExperienced:
                    {
                      StageActivityExperienced (agents [i]);
                      break;
                    }
                      //------------------------------------------------------------------------
                      //Search
                    case S_ABHA_Agent::stateSearch:
                    {
                      StageActivitySearch (agents [i]);
                      break;
                    }
                      //------------------------------------------------------------------------
                      //Food source
                    case S_ABHA_Agent::stateSource:
                    {
                      StageActivitySource (agents [i]);
                      break;
                    }
                  }
                  //--------------------------------------------------------------------------
                  for (int c = 0; c < coords; c++)
                  {
                    agents [i].position [c] = u.SeInDiSp (agents [i].position [c], rangeMin [c], rangeMax [c], rangeStep [c]);
                    a      [i].c        [c] = agents [i].position [c];
                  }
                }
                for (int i = 0; i < popSize; i++) for (int c = 0; c < coords; c++) a [i].c [c] = agents [i].position [c];
              }
              //——————————————————————————————————————————————————————————————————————————————
              
              

              O método Revision da classe C_AO_ABHA é responsável por atualizar os estados dos agentes no algoritmo e executa várias ações essenciais relacionadas à avaliação e à atualização das posições e dos estados dos agentes. Ele não recebe parâmetros nem retorna valores, servindo para atualizar as informações sobre os estados e posições dos agentes com base em seu desempenho. Lógica do método:

              1. Busca pelo melhor agente:

              • A variável ind é inicializada com o valor "-1" para rastrear o índice do agente com o melhor custo.
              • Um laço percorre todos os agentes (até popSize) para buscar o melhor agente:
              • Se o custo do agente (a[i].f) for maior que o máximo atual (fB), fB é atualizado e o índice ind é armazenado.
              • Se um agente com o melhor custo foi encontrado (ou seja, ind não é igual a "-1"), a função ArrayCopy é chamada para copiar as coordenadas do melhor agente para o array cB.

              2. O laço percorre todos os agentes e atualiza o custo de cada agente (agents[i].cost) com base nos valores do array a.

              3. O método CalculateProbabilities é chamado para calcular as probabilidades de cada agente, com base em seus custos atuais. Estas probabilidades determinam como os agentes agirão na próxima etapa.

              4. O método CalculateAverageCost é chamado para calcular o custo médio de todos os agentes. Este valor é necessário para que as abelhas analisem seu próprio estado e decidam sobre possíveis transições para novos estados.

              5. Um laço percorre todos os agentes e, dependendo de seu estado atual, chama o método apropriado para alterar seu estado, como ChangingStateForNovice, ChangingStateForExperienced, e assim por diante.

              6. Um laço percorre todos os agentes e verifica se o custo atual do agente é maior que seu melhor custo registrado (bestCost):

              • Se sim, o bestCost é atualizado, e a posição atual do agente é copiada para bestPosition.
              • O custo anterior (prevCost) é atualizado com o valor atual de cost.

              O significado final do método Revision é gerenciar a atualização das informações sobre os estados dos agentes no algoritmo e executar as seguintes ações principais:

              1. Identificar o agente com o melhor custo e atualizar as variáveis correspondentes.

              2. Atualizar os custos de todos os agentes.

              3. Calcular as probabilidades com base nos custos atuais.

              4. Determinar o custo médio dos agentes.

              5. Atualizar os estados dos agentes de acordo com seu desempenho.

              6. Atualizar os melhores custos e posições dos agentes.

              Este método é uma parte crucial do algoritmo, pois garante a adaptação dos agentes com base nos resultados obtidos e possibilita o compartilhamento de informações entre eles.

              //——————————————————————————————————————————————————————————————————————————————
              void C_AO_ABHA::Revision ()
              {
                //----------------------------------------------------------------------------
                int ind = -1;
              
                for (int i = 0; i < popSize; i++)
                {
                  if (a [i].f > fB)
                  {
                    fB = a [i].f;
                    ind = i;
                  }
                }
              
                if (ind != -1) ArrayCopy (cB, a [ind].c, 0, 0, WHOLE_ARRAY);
              
                //----------------------------------------------------------------------------
                for (int i = 0; i < popSize; i++) agents [i].cost = a [i].f;
              
                //----------------------------------------------------------------------------
                //Calculate the probabilities for bees at the current cost
                CalculateProbabilities ();
              
                //----------------------------------------------------------------------------
                //Calculate the average cost
                CalculateAverageCost ();
              
                //----------------------------------------------------------------------------
                //update bees' states (novice, experienced, search, source) 
                for (int i = 0; i < popSize; i++)
                {
                  switch (agents [i].state)
                  {
                    case S_ABHA_Agent::stateNovice:
                    {
                      ChangingStateForNovice (agents [i]);
                      break;
                    }
                    case S_ABHA_Agent::stateExperienced:
                    {
                      ChangingStateForExperienced (agents [i]);
                      break;
                    }
                    case S_ABHA_Agent::stateSearch:
                    {
                      ChangingStateForSearch (agents [i]);
                      break;
                    }
                    case S_ABHA_Agent::stateSource:
                    {
                      ChangingStateForSource (agents [i]);
                      break;
                    }
                  }
                }
                //----------------------------------------------------------------------------
                //Update the cost for bees
                for (int i = 0; i < popSize; i++)
                {
                  if (agents [i].cost > agents [i].bestCost)
                  {
                    agents [i].bestCost = agents [i].cost;
              
                    ArrayCopy (agents [i].bestPosition, agents [i].position);
                  }
                  agents [i].prevCost = agents [i].cost;
                }
              }
              //——————————————————————————————————————————————————————————————————————————————
              
              


              Considerações finais

              Neste artigo, exploramos o algoritmo do ABHA, analisamos detalhadamente seus princípios de funcionamento, escrevemos o pseudocódigo do algoritmo e descrevemos sua estrutura, classe, inicialização e os métodos Moving e Revision. Na próxima parte, continuaremos a implementação do código do algoritmo, cobriremos os demais métodos e, como de costume, realizaremos testes em funções de benchmark, além de apresentar os resultados na tabela de classificação.

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

              Arquivos anexados |
              ABHA.zip (29.82 KB)
              Simulação de mercado (Parte 05): Iniciando a classe C_Orders (II) Simulação de mercado (Parte 05): Iniciando a classe C_Orders (II)
              Neste artigo, explicarei como o Chart Trade conseguirá lidar, junto com o Expert Advisor, a um pedido do usuário para encerrar todas as posições que se encontram em aberto. Parece ser algo simples. Porém existem alguns agravantes que você precisa saber como lidar com eles.
              Redes neurais em trading: Resultados práticos do método TEMPO Redes neurais em trading: Resultados práticos do método TEMPO
              Damos continuidade à exploração do método TEMPO. Neste artigo, avaliaremos a eficácia prática das abordagens propostas com base em dados históricos reais.
              Do básico ao intermediário: Template e Typename (IV) Do básico ao intermediário: Template e Typename (IV)
              Aqui neste artigo, iremos ver de forma bem didática, como resolver um problema que foi demonstrado no final do artigo anterior. Onde estaríamos tentando fazer com que um template de tipo fosse criado, a fim de que fosse possível criar um template de uma união de dados.
              Simulação de mercado (Parte 04): Iniciando a classe C_Orders (I) Simulação de mercado (Parte 04): Iniciando a classe C_Orders (I)
              Neste artigo vamos começar a montar a classe C_Orders, para poder enviar pedidos ao servidor de negociação. Vamos fazer isto aos pouco. Já que o intuito será explicar o mais detalhadamente possível como isto será feito, via sistema de mensagens.