English Русский 中文 Español Deutsch 日本語
preview
Algoritmos de otimização populacionais: Algoritmo semelhante ao eletromagnetismo (EM)

Algoritmos de otimização populacionais: Algoritmo semelhante ao eletromagnetismo (EM)

MetaTrader 5Exemplos | 13 julho 2023, 10:12
214 0
Andrey Dik
Andrey Dik

Conteúdo

1. Introdução
2. Descrição do algoritmo
3. Resultado dos testes


1. Introdução

Nas últimas décadas, diversos métodos de busca metaheurística surgiram globalmente, desenhados por pesquisadores para resolver problemas de otimização complexos. Estes métodos também apresentam formas de aprimorá-los.

O algoritmo semelhante ao eletromagnetismo (EM), uma novidade nessa gama de ferramentas, é baseado na simulação do comportamento de partículas eletromagnéticas no espaço físico e foi apresentado ao mundo por I. Birbil e S.C. Fang em 2003. É caracterizado como um algoritmo evolutivo, que combina aleatoriedade e uma população de partículas influenciadas pela força de interação eletromagnética.

Este algoritmo aproveita a lógica de atração e repulsão de cargas da teoria do eletromagnetismo para solucionar problemas de otimização não linear sem restrições em um domínio contínuo. Graças à sua eficácia ao lidar com intrincados problemas de otimização global, o EM se tornou uma ferramenta de otimização amplamente empregada em diversas áreas.

Vamos falar um pouco sobre o fascinante mundo do eletromagnetismo e das cargas elétricas:

  • Existem dois tipos de carga elétrica: a positiva e a negativa. Cada carga corresponde a um sinal - positivo ou negativo.
  • O campo eletromagnético tem a capacidade de transmitir informações através de ondas de rádio. Utilizamos isso diariamente, seja para escutar rádio ou assistir à TV.
  • Nosso planeta tem um campo magnético que nos protege do vento solar e dos raios cósmicos.
  • Existem materiais que podem ser magnetizados, o que permite a criação de eletroímãs. Estes são empregados em diversas aplicações, como na geração de energia.
  • Há uma vasta gama de aplicações que se baseiam no eletromagnetismo. Por exemplo, computadores, celulares e outros dispositivos funcionam graças à tecnologia eletromagnética.
  • Todos os objetos que emitem luz, como lâmpadas e faróis de carros, lançam radiação eletromagnética.
  • O eletromagnetismo também tem um papel fundamental na medicina. Equipamentos médicos, como a ressonância magnética e a tomografia computadorizada, utilizam campos eletromagnéticos para gerar imagens do interior do corpo.
  • Alguns animais, como tubarões e enguias elétricas, podem usar o eletromagnetismo para se orientar no espaço.
  • O eletromagnetismo é uma das quatro interações fundamentais da natureza, que também inclui as interações gravitacional, fraca e forte.


2. Descrição do algoritmo

Baseado na teoria do eletromagnetismo, o EM simula o mecanismo de atração e repulsão de cargas para alcançar uma solução ótima global utilizando variáveis limitadas. No algoritmo, todas as soluções são consideradas como partículas carregadas no espaço de busca, e a carga de cada partícula está relacionada ao valor da função objetivo. As partículas com o melhor desempenho objetivo aplicam forças de atração, enquanto as partículas com piores valores objetivos aplicam forças de repulsão em relação às outras partículas. Quanto melhor o valor da função objetivo, maior será a magnitude da atração ou repulsão entre as partículas.

O princípio de funcionamento do algoritmo é o seguinte: inicialmente, é gerada uma população de soluções aleatórias, sendo que cada solução é representada por um vetor de coordenadas correspondentes às cargas das partículas eletromagnéticas. Em seguida, a cada iteração do algoritmo, ocorre a simulação do movimento dessas cargas no espaço sob a influência de forças eletromagnéticas. Durante o movimento, cada carga interage com as outras cargas, resultando em alterações na direção e velocidade. Consequentemente, ocorre uma convergência gradual das soluções em direção ao valor ótimo da função objetivo.

Os principais componentes do EM são os seguintes:

  1. Formação da população inicial de soluções (cargas), em que cada carga é representada por um vetor de coordenadas que corresponde a uma solução específica para o problema de otimização.
  2. Cálculo da força eletromagnética de interação entre as cargas. Esse cálculo é realizado em cada iteração do algoritmo e depende da distância entre as cargas (soluções).
  3. Movimento das cargas no espaço sob a influência das forças eletromagnéticas de interação.
  4. Atualização da população de soluções em cada iteração com base em uma função objetivo (por exemplo, uma função de perda em problemas de aprendizado de máquina).
  5. Definição de um critério de parada para o algoritmo, como atingir um determinado valor da função objetivo.

Durante a execução do algoritmo, as partículas interagem umas com as outras, atraindo-se ou repelindo-se com base em suas cargas e na distância entre elas. O algoritmo é executado em várias iterações, em cada uma das quais as coordenadas e cargas das partículas são atualizadas, e novos valores da função de adaptação são calculados.

A unidade lógica do algoritmo do EM é a partícula, que pode ser descrita pela estrutura S_Particle, representando um agente no espaço de busca. Cada partícula possui coordenadas c [], que determinam sua posição no espaço de busca, e uma carga C, que influencia a interação com outras partículas. Para cada partícula, é calculado o valor da função de adaptação f, que avalia a qualidade da solução correspondente a essas coordenadas. Além disso, são calculadas as distâncias R para as demais partículas e os vetores de força F, que definem a direção do movimento da partícula no espaço de busca.

//——————————————————————————————————————————————————————————————————————————————
struct S_Particle
{
  double c  [];   //coordinates
  double C;       //charge
  double f;       //fitness
  double R  [];   //euclidean distance to other particles
  double F  [];   //force vector
};
//——————————————————————————————————————————————————————————————————————————————

A classe C_AO_EM é uma implementação do EM. É usada para encontrar os valores ideais de uma função definida em um conjunto de números reais. O algoritmo se baseia na simulação dos processos de interação de partículas magnéticas e elétricas em um sistema físico.

A classe contém os seguintes campos:

  • S_Particle p[] — array de partículas que representam soluções potenciais para o problema de otimização.
  • double rangeMax[] — array de valores máximos do intervalo de pesquisa para cada coordenada.
  • double rangeMin[] — array de valores mínimos do intervalo de pesquisa para cada coordenada.
  • double rangeStep[] — array de passos de pesquisa para cada coordenada.
  • double cB[] — array de coordenadas da melhor solução.
  • double fB — valor da função da melhor solução.

A classe contém os seguintes métodos:

  • void Init() — inicializa o algoritmo definindo o número de coordenadas, o número de partículas, a constante do ambiente e a etapa do movimento.
  • void Moving(int iter) — itera o algoritmo, movendo as partículas de acordo com as regras de interação entre os campos magnético e elétrico.
  • void Revision() — revisa partículas, verificando se elas estão fora do intervalo de busca e corrigindo sua posição, se necessário.

A classe também contém campos privados:

  • int coordinatesNumber — número de coordenadas.
  • int particlesNumber — número de partículas.
  • double envConstant — constante de ambiente.
  • double movConstant — etapa do movimento.
  • double exponent — medida do expoente de distância.
  • double vect[] — array de vetores.
  • bool revision — sinalizador que indica a necessidade de revisão da partícula.

A classe contém métodos privados:

  • double SeInDiSp(double In, double InMin, double InMax, double Step) — distribui os pontos em uma grade uniforme.
  • double RNDfromCI(double min, double max) — gera um número aleatório dentro de um determinado intervalo.
//——————————————————————————————————————————————————————————————————————————————
class C_AO_EM
{
  //----------------------------------------------------------------------------
  public: S_Particle p     []; //particles
  public: double rangeMax  []; //maximum search range
  public: double rangeMin  []; //minimum search range
  public: double rangeStep []; //step search
  public: double cB        []; //best coordinates
  public: double fB;           //FF of the best coordinates

  public: void Init (const int    coordinatesNumberP, //coordinates number
                     const int    particlesNumberP,   //particles number
                     const double envConstantP,       //environmental constant
                     const double movConstantP,       //movement step
                     const double exponentP);         //exponent

  public: void Moving   ();
  public: void Revision ();

  //----------------------------------------------------------------------------
  private: int    coordinatesNumber; //coordinates number
  private: int    particlesNumber;   //particles number
  private: double envConstant;       //environmental constant
  private: double movConstant;       //movement step
  private: double exponent;          //exponent
  private: double vect    [];        //vector
  private: bool   revision;

  private: double SeInDiSp  (double In, double InMin, double InMax, double Step);
  private: double RNDfromCI (double min, double max);
};
//——————————————————————————————————————————————————————————————————————————————

O método de inicialização do EM começa redefinindo o gerador de números aleatórios e definindo valores iniciais para algumas variáveis. Em seguida, o método utiliza vários parâmetros como entrada: o número de coordenadas, o número de partículas, o valor do ambiente e a etapa de movimento. Logo após, o método cria vários arrays do tamanho necessário e os preenche com valores iniciais.

Os arrays armazenam os valores máximo e mínimo do intervalo para cada coordenada, a etapa de alteração da coordenada, o vetor e a posição atual de cada partícula. Além disso, o método cria um array de partículas e, para cada partícula, cria arrays para armazenar suas coordenadas, uma matriz de distâncias em relação às outras partículas, um vetor de forças e o valor atual da melhor função. Por fim, o método cria um array para armazenar a melhor coordenada de todas as partículas. Dessa forma, o método inicializa todas as variáveis e arrays necessários para o funcionamento do EM.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_EM::Init (const int    coordinatesNumberP, //coordinates number
                    const int    particlesNumberP,   //particles number
                    const double envConstantP,       //environmental constant
                    const double movConstantP,       //movement step
                    const double exponentP)          //exponent
{
  MathSrand ((int)GetMicrosecondCount ()); // reset of the generator
  fB       = -DBL_MAX;
  revision = false;

  coordinatesNumber = coordinatesNumberP;
  particlesNumber   = particlesNumberP;
  envConstant       = envConstantP;
  movConstant       = movConstantP;
  exponent          = exponentP;

  ArrayResize (rangeMax,  coordinatesNumber);
  ArrayResize (rangeMin,  coordinatesNumber);
  ArrayResize (rangeStep, coordinatesNumber);
  ArrayResize (vect,      coordinatesNumber);

  ArrayResize (p,  particlesNumber);

  for (int i = 0; i < particlesNumber; i++)
  {
    ArrayResize (p [i].c,  coordinatesNumber);
    ArrayResize (p [i].R,  particlesNumber);
    ArrayResize (p [i].F,  coordinatesNumber);
    p [i].f  = -DBL_MAX;
  }

  ArrayResize (cB, coordinatesNumber);
}
//——————————————————————————————————————————————————————————————————————————————

O método Moving() é o primeiro método obrigatório em cada iteração. Ele é responsável pelo movimento das partículas no espaço de solução. Primeiramente, o método verifica se as partículas já foram inicializadas. Caso contrário, cada partícula recebe coordenadas aleatórias dentro dos limites fornecidos e zera sua pontuação e carga atual. Também é calculado o vetor de diferenças vect [] entre os valores máximo e mínimo em cada dimensão do espaço de busca.

//----------------------------------------------------------------------------
if (!revision)
{
  fB = -DBL_MAX;

  for (int obj = 0; obj < particlesNumber; obj++)
  {
    for (int c = 0; c < coordinatesNumber; c++)
    {
      p [obj].c [c] = RNDfromCI (rangeMin [c], rangeMax [c]);
      p [obj].c [c] = SeInDiSp (p [obj].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
      p [obj].C     = 0.0;
      p [obj].f     = -DBL_MAX;
    }
  }

  for (int c = 0; c < coordinatesNumber; c++)
  {
    vect [c] = rangeMax [c] - rangeMin [c];
  }

  revision = true;
}

Se a inicialização já tiver sido realizada, o método calcula a carga de cada partícula com base em seu desvio em relação ao máximo global, normalizado pela soma dos desvios do máximo global de todas as partículas. O cálculo da soma das diferenças é feito da seguinte forma:

//calculate the sum of the differences of the fitness of the particles with the global value
for (int obj = 0; obj < particlesNumber; obj++)
{
  sumDiff += fB - p [obj].f;
}

A carga da partícula é calculada utilizando a fórmula:

p [obj].C = exp (-particlesNumber * ((fB - p [obj].f) / sumDiff));
Como podemos observar, o valor da carga na fórmula é um número positivo; o sinal da carga será considerado posteriormente no algoritmo. Se a soma das diferenças do máximo global for zero, presume-se que a carga da partícula seja zero. A carga calculada da partícula determinará a magnitude da força exercida pela partícula sobre as outras partículas correspondentes na etapa de cálculo da força. O código para o cálculo da carga da partícula terá a seguinte aparência:

//calculating the charge of particles=======================================
for (int obj = 0; obj < particlesNumber; obj++)
{
  if (sumDiff == 0.0)
  {
    p [obj].C = 0.0;
  }
  else
  {
    p [obj].C = exp (-particlesNumber * ((fB - p [obj].f) / sumDiff));
  }
}

Antes de prosseguirmos com o cálculo das distâncias entre as partículas, é necessário zerar o array de distâncias da partícula em relação às outras partículas, assim como o array de forças que atuam sobre a partícula:

//calculation of Euclidean distances between all particles==================
for (int obj = 0; obj < particlesNumber; obj++)
{
  ArrayInitialize (p [obj].R, 0.0);
  ArrayInitialize (p [obj].F, 0.0);
}

Em seguida, são calculadas as distâncias entre todos os pares de partículas e as forças que atuam entre elas. Aqui, é utilizada uma fórmula baseada na lei de Coulomb, que descreve a interação entre partículas carregadas. As forças que atuam sobre cada partícula são calculadas como a soma vetorial de todas as forças provenientes das outras partículas.

De acordo com a teoria eletromagnética, a força exercida por uma partícula sobre outra é inversamente proporcional à distância entre as duas partículas e diretamente proporcional ao produto de suas cargas. Uma partícula com um valor-alvo mais baixo exerce uma força repulsiva sobre uma partícula com um valor-alvo relativamente mais alto. Da mesma forma, ela repele uma partícula boa de uma região com um valor-alvo ruim. Por outro lado, uma partícula com um valor-alvo mais alto exerce uma atração sobre partículas com valores relativamente mais baixos.

Levando em consideração todas as forças relevantes criadas pelas demais partículas, é calculado o vetor de força total para cada partícula. Esse vetor de força combinado determina a direção na qual a partícula se moverá durante a etapa de movimento. Os autores do algoritmo recomendam normalizar o vetor de força de uma partícula pelo vetor de força entre todas as partículas. No entanto, meus experimentos mostraram que, sem a normalização, os resultados são melhores, e o código é apresentado sem a normalização.

Dependendo de qual partícula possui o maior valor da função objetivo, determinamos a direção da força (simulando o sinal da carga).

for (int obj = 0; obj < particlesNumber; obj++)
{
  for (int obj2 = 0; obj2 < particlesNumber; obj2++)
  {
    if (obj != obj2)
    {
      if (p [obj].R [obj2] == 0.0)
      {
        for (int c = 0; c < coordinatesNumber; c++)
        {
          diffDist = p [obj].c [c] - p [obj2].c [c];
          p [obj].R [obj2] += diffDist * diffDist;
        }

        p [obj].R [obj2] = sqrt (p [obj].R [obj2]);
        p [obj2].R [obj] = p [obj].R [obj2];

        //calculation of the force------------------------------------------
        Fp = p [obj].C * p [obj2].C / (4.0 * M_PI * envConstant * pow (p [obj].R [obj2], exponent));

        for (int c = 0; c < coordinatesNumber; c++)
        {
          if (p [obj].f > p [obj2].f)
          {
            p [obj ].F [c] += (p [obj2].c [c] - p [obj].c [c]) * Fp;
            p [obj2].F [c] -= (p [obj2].c [c] - p [obj].c [c]) * Fp;

          }
          else
          {
            p [obj ].F [c] -= (p [obj2].c [c] - p [obj].c [c]) * Fp;
            p [obj2].F [c] += (p [obj2].c [c] - p [obj].c [c]) * Fp;
          }
        }
      }
    }
  }
}

Por fim, são calculadas novas coordenadas para cada partícula com base em sua posição atual e na força que atua sobre ela. É importante observar que as partículas não possuem massa e, portanto, não têm aceleração. Diferentemente do algoritmo de busca por gravidade (GSA), as partículas se movem instantaneamente para uma nova posição. As coordenadas de movimento são limitadas ao intervalo de busca e à mudança de etapa.

O código comentado retorna a partícula no lado oposto do intervalo a uma distância da respectiva coordenada, caso a partícula esteja fora do intervalo válido.

//calculation of particle motions===========================================
for (int obj = 0; obj < particlesNumber; obj++)
{
  for (int c = 0; c < coordinatesNumber; c++)
  {
    r = RNDfromCI (0.0, 1.0);
    p [obj].c [c] = p [obj].c [c] + r * p [obj].F [c] * vect [c] * movConstant;

    //if (p [obj].c [c] > rangeMax [c]) p [obj].c [c] = rangeMin [c] + (p [obj].c [c] - rangeMax [c]);
    //if (p [obj].c [c] < rangeMin [c]) p [obj].c [c] = rangeMax [c] - (rangeMin [c] - p [obj].c [c]);

    p [obj].c [c] = SeInDiSp (p [obj].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
  }
}

O método Revision(), o segundo método obrigatório em cada iteração do algoritmo do EM, é responsável por verificar a melhor posição da partícula na iteração atual. O método percorre todas as partículas e compara o valor de sua função de adaptação com o melhor valor atual, fB. Se o valor da função de adaptação da partícula atual for maior que fB, então fB é atualizado e a posição da partícula é copiada para o array cB.

Dessa forma, o método Revision() mantém o controle da melhor posição da partícula em cada iteração do algoritmo e a armazena no array cB. Isso auxilia na otimização do processo de busca pela solução ideal e aumenta a eficiência do algoritmo.

//——————————————————————————————————————————————————————————————————————————————
void C_AO_EM::Revision ()
{
  for (int s = 0; s < particlesNumber; s++)
  {
    if (p [s].f > fB)
    {
      fB = p [s].f;
      ArrayCopy (cB, p [s].c, 0, 0, WHOLE_ARRAY);
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

O método SeInDiSp() no algoritmo do EM é utilizado para limitar os valores da variável In a um intervalo específico [InMin, InMax] com a etapa Step. Se In for menor ou igual a InMin, o método retorna InMin. Se In for maior ou igual a InMax, o método retorna InMax. Se a etapa for igual a zero, o método retorna o valor original de In. Caso contrário, o método calcula o novo valor de In utilizando a fórmula: InMin + Step * (In - InMin) / Step, onde MathRound() é um método para arredondar um número para o inteiro mais próximo.

Assim, o método SeInDiSp() permite controlar a alteração no valor da variável In dentro de um intervalo específico e com uma determinada etapa, o que auxilia na otimização da função de forma mais eficiente e rápida.

//——————————————————————————————————————————————————————————————————————————————
// Choice in discrete space
double C_AO_EM::SeInDiSp (double In, double InMin, double InMax, double Step)
{
  if (In <= InMin) return (InMin);
  if (In >= InMax) return (InMax);
  if (Step == 0.0) return (In);
  else return (InMin + Step * (double)MathRound ((In - InMin) / Step));
}
//——————————————————————————————————————————————————————————————————————————————


3. Resultado dos testes

Saída do EM na bancada de teste:

2023.03.26 18:27:39.259    C_AO_EM:50;0.1;0.8
2023.03.26 18:27:39.259    =============================
2023.03.26 18:27:43.215    5 Rastrigin's; Func runs 10000 result: 59.939529106561224
2023.03.26 18:27:43.215    Score: 0.74268
2023.03.26 18:27:52.960    25 Rastrigin's; Func runs 10000 result: 59.780143424645416
2023.03.26 18:27:52.960    Score: 0.74071
2023.03.26 18:29:22.856    500 Rastrigin's; Func runs 10000 result: 63.94951378068386
2023.03.26 18:29:22.856    Score: 0.79237
2023.03.26 18:29:22.856    =============================
2023.03.26 18:29:28.901    5 Forest's; Func runs 10000 result: 0.28698617113254693
2023.03.26 18:29:28.901    Score: 0.16233
2023.03.26 18:29:38.103    25 Forest's; Func runs 10000 result: 0.1571444033424823
2023.03.26 18:29:38.103    Score: 0.08889
2023.03.26 18:30:53.341    500 Forest's; Func runs 10000 result: 0.11734383105881332
2023.03.26 18:30:53.341    Score: 0.06638
2023.03.26 18:30:53.341    =============================
2023.03.26 18:30:58.108    5 Megacity's; Func runs 10000 result: 1.3599999999999999
2023.03.26 18:30:58.108    Score: 0.11333
2023.03.26 18:31:08.897    25 Megacity's; Func runs 10000 result: 0.776
2023.03.26 18:31:08.897    Score: 0.06467
2023.03.26 18:32:23.199    500 Megacity's; Func runs 10000 result: 0.34320000000000006
2023.03.26 18:32:23.199    Score: 0.02860
2023.03.26 18:32:23.199    =============================
2023.03.26 18:32:23.199    All score: 2.79996

Ao observar as animações do algoritmo ME nas funções de teste, é possível imaginar uma espécie de "eletrização" do campo do espaço de busca. As partículas formam grupos de cargas elevadas, seguindo as características da superfície da função de teste. É evidente, desde logo, a baixa qualidade de convergência, porém o EM pode proporcionar uma imagem visualmente atraente.

rastrigin

  EM na função de teste de Rastrigin.

forest

  EM na função de teste Forest.

megacity

  EM na função de teste Megacity.

Vamos agora aos resultados do teste do EM. Apresentou um desempenho abaixo da média da tabela, com uma pontuação final de 22. O algoritmo teve um desempenho fraco em quase todos os seis testes. A exceção é o teste da função Rastrigin com 1.000 parâmetros, no qual o EM teve um desempenho superior nessa disciplina de teste em relação a algoritmos mais poderosos, como SSG e BA. Além disso, os valores absolutos da função com 1.000 parâmetros foram ainda maiores do que nos testes com 10 e 50 parâmetros!

Isso é algo sem precedentes em minha memória, pois geralmente, à medida que o número de parâmetros a serem otimizados aumenta, os resultados da pesquisa melhoram. Esse fenômeno provavelmente está relacionado às peculiaridades da própria estratégia de busca do EM. É importante observar a sensibilidade do EM à presença de um gradiente e à diferenciabilidade em todo o domínio da função em estudo.

AO

Description

Rastrigin

Rastrigin final

Forest

Forest final

Megacity (discrete)

Megacity final

Final result

10 params (5 F)

50 params (25 F)

1000 params (500 F)

10 params (5 F)

50 params (25 F)

1000 params (500 F)

10 params (5 F)

50 params (25 F)

1000 params (500 F)

SSG

mudas, semeando e crescimento

1,00000

1,00000

0,55665

2,55665

0,72740

0,94522

1,00000

2,67262

0,76364

0,85977

1,00000

2,62340

100,000

HS

busca de harmonia

0,99676

0,95282

0,48178

2,43136

1,00000

0,98931

0,44806

2,43736

1,00000

1,00000

0,41537

2,41537

92,329

ACOm

otimização de colônia de formigas M

0,34611

0,17985

0,17044

0,69640

0,86888

1,00000

0,77362

2,64249

1,00000

0,88930

0,05606

1,94536

65,347

IWO

otimização invasiva de ervas daninhas

0,95828

0,67083

0,29807

1,92719

0,70773

0,46349

0,31773

1,48896

0,80000

0,42067

0,33289

1,55356

61,104

COAm

algoritmo de otimização de cuco M

0,92400

0,46794

0,26004

1,65199

0,58378

0,34034

0,16526

1,08939

0,72727

0,33025

0,17083

1,22835

47,612

FAm

algoritmo de vaga-lumes M

0,59825

0,33980

0,17135

1,10941

0,51073

0,42299

0,49790

1,43161

0,34545

0,28044

0,35258

0,97847

41,537

ABC

colônia artificial de abelhas

0,78170

0,32715

0,20822

1,31707

0,53837

0,21455

0,13344

0,88636

0,56364

0,26569

0,13926

0,96858

36,849

GSA

algoritmo de busca gravitacional

0,70167

0,45217

0,00000

1,15384

0,31660

0,36416

0,33204

1,01280

0,59395

0,35054

0,00000

0,94448

36,028

BA

algoritmo do morcego

0,40526

0,63761

0,84451

1,88738

0,20841

0,17477

0,25989

0,64308

0,29698

0,09963

0,17371

0,57032

35,888

BFO

otimização de forrageamento bacteriano

0,67203

0,30963

0,11813

1,09979

0,39702

0,26623

0,20652

0,86976

0,52122

0,33211

0,18932

1,04264

34,693

EM

Algoritmo semelhante ao eletromagnetismo

0,12235

0,46278

1,00000

1,58513

0,00000

0,03498

0,34880

0,38377

0,00000

0,00000

0,10924

0,10924

22,091

MA

algoritmo do macaco

0,33192

0,33451

0,14644

0,81287

0,10012

0,07891

0,08932

0,26836

0,21818

0,04243

0,10720

0,36781

13,603

FSS

busca por cardume de peixes

0,46812

0,25337

0,11302

0,83451

0,12840

0,05013

0,06516

0,24369

0,16971

0,04796

0,08283

0,30050

12,655

PSO

otimização de enxame de partículas

0,20449

0,08200

0,07160

0,35809

0,18895

0,10486

0,21738

0,51119

0,23636

0,05903

0,01957

0,31496

10,031

RND

aleatório

0,16826

0,09743

0,08019

0,34589

0,13496

0,04810

0,04715

0,23021

0,16971

0,03875

0,04922

0,25767

5,302

GWO

otimizador lobo-cinzento

0,00000

0,00000

0,02256

0,02256

0,06570

0,00000

0,00000

0,06570

0,32727

0,07378

0,02557

0,42663

1,000


Conclusões

  1. O EM é um método eficiente de otimização capaz de resolver uma variedade de problemas de otimização, especialmente aqueles que envolvem o processamento de grandes quantidades de dados e alta dimensionalidade em funções suaves.
  2. O algoritmo se baseia na simulação do comportamento de partículas eletromagnéticas no espaço físico, o que permite obter resultados de alta precisão para funções multidimensionais complexas.
  3. O EM não requer cálculos de gradiente, tornando-o mais versátil e fácil de aplicar a diferentes problemas. No entanto, é importante destacar que o algoritmo é sensível à presença de um gradiente na função a ser otimizada.
  4. A grande vantagem do algoritmo é sua capacidade de ser modificado e ajustado de acordo com a tarefa de otimização específica, tornando-o uma ferramenta flexível para otimizar diferentes tipos de funções.
  5. Existem várias modificações do EM que podem ser aprimoradas em relação à versão básica e adaptadas a tarefas de otimização específicas.
  6. Por fim, o EM pode ser aplicado em diversas áreas, como aprendizado de máquina, inteligência artificial, otimização de mercados financeiros, entre outros.

A principal vantagem do algoritmo eletromagnético é sua capacidade de resolver problemas em espaços multidimensionais e de grandes dimensões, mantendo alta precisão no resultado.

Dessa forma, o EM se torna uma ferramenta eficiente para otimizar diversas funções e pode ser aplicado em uma ampla gama de problemas de otimização, especialmente quando há necessidade de processar grandes volumes de dados e/ou lidar com alta dimensionalidade.

Essa classificação pode ser útil na escolha do algoritmo mais adequado para resolver um problema específico de otimização. No entanto, é importante lembrar que a eficiência do algoritmo depende de diversos fatores, como o tamanho do problema, o tipo de função, o número de variáveis, entre outros. Portanto, a seleção do algoritmo deve ser baseada em uma análise completa da tarefa em questão, levando em consideração todas as suas particularidades.


O histograma de resultados do teste do algoritmo é apresentado na Figura 1.

chart

Figura 1. Histograma dos resultados finais dos testes dos algoritmos.

Prós e contras do EM:

Prós:
1. Simplicidade de implementação.
2. Escalabilidade impressionante em funções suaves.
3. Poucos parâmetros externos.

Contras:
1. Alta complexidade computacional.
2. Resultados não tão bons em funções discretas.
3. Dificuldade em superar áreas planas horizontais nas funções.

Anexei um arquivo a cada artigo contendo versões atualizadas dos códigos de algoritmo descritos em artigos anteriores. Os artigos são baseados na experiência acumulada e na opinião pessoal do autor, com conclusões e julgamentos baseados nos resultados de experimentos realizados.

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

Arquivos anexados |
Uso de modelos ONNX em MQL5 Uso de modelos ONNX em MQL5
O ONNX (Open Neural Network Exchange) é um padrão aberto para a representação de modelos de redes neurais. Neste artigo, consideraremos o processo de criação do modelo SNN-LSTM para previsão de séries temporais financeiras e o uso do modelo ONNX criado em um Expert Advisor MQL5.
Teoria das Categorias em MQL5 (Parte 4): Intervalos, experimentos e composições Teoria das Categorias em MQL5 (Parte 4): Intervalos, experimentos e composições
A teoria das categorias representa um segmento diversificado e em constante expansão da matemática, que até agora está relativamente pouco explorado na comunidade MQL5. Esta série de artigos tem como objetivo descrever alguns de seus conceitos a fim de criar uma biblioteca aberta e utilizar ainda mais essa seção notável na criação de estratégias de negociação.
Teoria das Categorias em MQL5 (Parte 5): Equalizadores Teoria das Categorias em MQL5 (Parte 5): Equalizadores
A teoria das categorias é um ramo diversificado e em expansão da matemática que só recentemente começou a ser abordado na comunidade MQL5. Esta série de artigos tem como objetivo analisar alguns de seus conceitos para criar uma biblioteca aberta e utilizar ainda mais essa maravilhosa seção na criação de estratégias de negociação.
Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 19): Ajustes necessários Desenvolvendo um sistema de Replay - Simulação de mercado (Parte 19): Ajustes necessários
O que de fato vamos fazer aqui, é preparar o terreno, de forma que quando for preciso adicionar algumas novas coisas ao código, isto aconteça de forma suave e tranquila. O código atual ainda não consegue cobrir ou dar cabo de algumas coisas, que serão necessárias para um avanço significativo. Precisamos que tudo seja construído de maneira que o esforço de implementação de algumas coisas seja o menor possível. Se isto for feito adequadamente teremos a possibilidade de ter um sistema realmente bastante versátil. Sendo capaz de se adaptar muito facilmente a qualquer situação que for preciso ser coberta.