English Русский
preview
Algoritmo de sistema artificial de circulação coronariana (Artificial Coronary Circulation System, ACCS)

Algoritmo de sistema artificial de circulação coronariana (Artificial Coronary Circulation System, ACCS)

MetaTrader 5Sistemas de negociação |
19 0
Andrey Dik
Andrey Dik

Conteúdo

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


Introdução

O Artificial Coronary Circulation System (ACCS) é um método meta-heurístico de otimização bioinspirado. O ACCS simula o crescimento das artérias coronárias do coração humano. A ideia é que cada artéria ou capilar represente uma solução candidata, enquanto todo o crescimento do sistema vascular corresponde à busca pelo ótimo em um espaço de soluções complexo. O algoritmo foi proposto por A. Kaveh e M. Kooshkbaghi em 2019, no artigo "Artificial coronary circulation system: A new bio-inspired metaheuristic algorithm".


Implementação do algoritmo

Imagine que seu coração não seja apenas uma bomba, mas um arquiteto sábio que constrói as melhores rotas para o sangue. A cada segundo, ele resolve uma tarefa extremamente complexa: como transportar o máximo de oxigênio com o mínimo de gasto energético. Os cientistas observaram essa estratégia engenhosa da natureza e decidiram usá-la como base para criar o algoritmo ACCS. 

No início, há caos. Assim como na natureza, quando os capilares começam a se desenvolver, o ACCS cria uma população aleatória de soluções. O líder capilar (CL), que começa a buscar um caminho até a solução ótima, é avaliado pelo fator de crescimento coronariano (CGF), uma espécie de nível de energia que indica quão bem ele está se saindo na tarefa. Cada capilar escolhe como crescer: busca, avançando como uma raiz na esperança de encontrar solo fértil; ramificação, criando novos ramos quando as condições são favoráveis, como uma árvore que lança novos brotos; ou poda, interrompendo o crescimento quando ele não traz benefício, para evitar o desperdício de recursos.

Memória do coração. Para não esquecer quais ramos foram os mais fortes, o ACCS utiliza a Heart Memory (HM), uma espécie de diário no qual são registradas as melhores soluções. Esses registros servem de referência para o crescimento e ajudam os novos capilares a avançar na direção mais promissora.

Autoaprendizado e adaptação. Se um capilar cresce em uma direção desfavorável, o algoritmo ativa a busca local e passa a explorar a região ao redor, como uma raiz procurando água. Se, de repente, esse capilar se torna o melhor, é iniciada uma busca global, como se uma árvore decidisse crescer em uma nova direção.

O ACCS não é apenas matemática fria, mas uma verdadeira arte de aprender com a natureza. Ao longo de toda a vida, o coração resolve tarefas de otimização extremamente complexas, e agora os algoritmos podem aproveitar essa mesma lógica: diversificar a busca, como fazem as artérias coronárias; preservar as melhores soluções, como a memória do coração; descartar tentativas malsucedidas, como na poda dos vasos; e manter o equilíbrio entre a busca global e o refinamento local.

Esse algoritmo nos lembra que as melhores soluções muitas vezes já existem na natureza. Basta saber observá-las e aprender com a sabedoria que pulsa no peito de cada um de nós. Podemos ver como isso funciona na ilustração.

coronary_system

Figura 1. Sistema coronariano

A imagem mostra os principais elementos: uma representação esquemática do coração com as artérias coronárias. A artéria coronária esquerda (LCA), com seus ramos: LAD e Circumflex; a artéria coronária direita (RCA); pequenos capilares, que demonstram a busca local; e, na parte superior direita, o padrão de bifurcação (ramificação).

Conceitos do algoritmo. Na parte inferior, é mostrado como os elementos biológicos correspondem aos componentes do algoritmo:

Artérias principais → Busca global
Bifurcação → Fator de ramificação
Capilares → Busca local
Fluxo sanguíneo → CGF (fator de crescimento)

Essa representação visual ajuda a entender como o sistema natural de irrigação do coração inspirou a criação do algoritmo de otimização, no qual as "artérias" exploram o espaço de soluções e os "capilares" fazem o refinamento das soluções encontradas. Vamos escrever o pseudocódigo do algoritmo.

  1. Inicialização

    • Definir os parâmetros: tamanho da população (popSize) e tamanho da memória do coração (heartMemorySize)

    • Criar a população inicial de capilares (agentes) com posições aleatórias no espaço de soluções

    • Inicializar a memória do coração (Heart Memory) para armazenar as melhores soluções

  2. Laço principal (até que o critério de parada seja atingido)

    • Calcular o fator de crescimento coronariano (CGF) de cada agente com base em seus valores de fitness

    • Executar a busca global (crescimento das artérias): atualizar as posições dos agentes, movendo-os em direção ao centro da população ou para longe dele, dependendo do CGF

    • Verificar os limites e atualizar a memória do coração

    • Executar a busca local (crescimento dos capilares): atualizar as posições dos agentes, movendo-os na direção do melhor agente e para longe do pior, levando em conta o fator de angiogênese

    • Verificar os limites e atualizar a memória do coração

    • Incrementar o contador de iterações

  3. Cálculo do CGF (Coronary Growth Factor)

    • Para cada agente, calcular o CGF como seu fitness dividido pela soma dos valores de fitness de todos os agentes (normalização)

  4. Busca global (Global Search)

    • Calcular o centro da população (média de todas as coordenadas)

    • Para cada agente:

      • selecionar aleatoriamente outro agente, exceto o próprio agente atual;

      • determinar a direção do movimento (dr): se o CGF do centro for menor que o CGF do agente atual, então dr = -1 (afastar-se do centro); caso contrário, dr = 1 (mover-se em direção ao centro);

      • atualizar a posição: nova posição = posição do agente aleatório + dr × CGF do agente atual × (centro - posição do agente aleatório).

  5. Busca local (Local Search)

    • Calcular o fator de angiogênese (alpha) como angiogenesisPower * sqrt(iteração_atual / iteração_máxima)

    • Encontrar o melhor e o pior agente da população atual

    • Para cada agente, atualizar a posição: nova posição = posição atual + alpha × número_aleatório × (posição_do_melhor - posição_do_pior)

  6. Atualização da memória do coração (Heart Memory)

    • Ordenar os agentes pelos valores de fitness em ordem decrescente

    • Armazenar na memória do coração os heartMemorySize melhores agentes

  7. Critério de parada

    • O número máximo de iterações foi atingido

Vamos observar a seguir o esquema de funcionamento do algoritmo.

ACCS

Figura 2. Fluxograma do algoritmo ACCS

Etapas do algoritmo mostradas no fluxograma:

  • inicialização da população de capilares (posições aleatórias),
  • cálculo da função de fitness de cada capilar,
  • cálculo do Coronary Growth Factor (CGF),
  • busca global (movimento em direção ao centro ou para longe dele),
  • busca local (movimento em direção ao melhor agente e para longe do pior),
  • poda (se a nova posição for pior, retornar à posição anterior),
  • atualização da memória do coração,
  • verificação do critério de parada.

Agora já temos uma ideia mais clara de como tudo deve funcionar, então podemos começar a escrever o código do algoritmo. Temos duas estruturas de dados relacionadas, destinadas à otimização e ao armazenamento de informações sobre as soluções.

A primeira estrutura, chamada "Memória do coração" (Heart Memory), é destinada ao armazenamento temporário e à avaliação das melhores soluções encontradas e contém:

  • Posição: conjunto de valores numéricos que define uma solução específica no espaço de busca. Esses valores podem ser considerados as coordenadas dessa solução.
  • Fitness: valor numérico que indica a "qualidade" da posição correspondente. Quanto maior o fitness, melhor a solução.
  • Inicialização: componente da estrutura que permite definir o tamanho da posição (número de dimensões) e atribuir ao fitness um valor inicial extremamente baixo, para que qualquer solução encontrada seja considerada melhor.

A segunda estrutura, chamada "Posição temporária" (TempPosition), é usada para armazenar temporariamente soluções novas, recém-geradas ou calculadas, antes que sejam avaliadas e salvas na "Memória do coração". Ela inclui:

  • Coordenadas: assim como a "posição" da primeira estrutura, trata-se de um conjunto de valores numéricos que define uma solução específica.
  • Fitness: valor numérico que será atribuído a essa solução após sua avaliação.
  • Inicialização: assim como na primeira estrutura, esse componente permite definir o tamanho das coordenadas (número de dimensões) e atribuir ao fitness um valor inicial extremamente baixo até que a solução seja totalmente processada.
//————————————————————————————————————————————————————————————————————
// Structure for storing Heart Memory
struct S_HeartMemory
{
    double position [];  // position in memory
    double fitness;      // position fitness

    void Init (int dimensions)
    {
      ArrayResize (position, dimensions);
      fitness = -DBL_MAX;
    }
};

// A structure for temporarily storing new positions
struct S_TempPosition
{
    double coords [];   // coordinates
    double fitness;     // fitness
    
    void Init (int dimensions)
    {
      ArrayResize (coords, dimensions);
      fitness = -DBL_MAX;
    }
};
//————————————————————————————————————————————————————————————————————

A classe "C_AO_ACCS" implementa o algoritmo de otimização denominado "Sistema de circulação coronariana artificial" (Artificial Coronary Circulation System, ACCS). Essa classe herda da classe base "AO".

Campos públicos (public) da classe:

  • Destrutor: função especial executada quando um objeto dessa classe é destruído, realizando a liberação dos recursos utilizados.
  • Construtor: função chamada durante a criação de um novo objeto, responsável por inicializar os principais parâmetros do algoritmo:
    • Define o tamanho padrão da população como 25, ou seja, o número de "capilares".
    • Define o coeficiente de bifurcação padrão como 0,5.
    • Cria a estrutura destinada a armazenar os parâmetros ajustáveis e registra nela os valores iniciais de "popSize" e "bifurcationRate".
  • SetParams(): função destinada a definir ou atualizar os parâmetros do algoritmo. Ela lê os valores atuais dos parâmetros listados e também define o tamanho da "memória do coração" como 25% do tamanho da população, com valor mínimo de 1.
  • Init(): função destinada à inicialização do algoritmo. Recebe informações sobre os intervalos de busca, os passos e o número de épocas (iterações).
  • Moving(): função responsável pelo deslocamento ou pela atualização dos agentes (capilares) no espaço de busca.
  • Revision(): função responsável pela revisão e pelo ajuste das soluções de acordo com a lógica do algoritmo.
  • bifurcationRate: coeficiente de bifurcação que influencia a geração de novas soluções e a ramificação da busca.

Campos privados (private) da classe:

  • CalculateCGF(): função interna que calcula o fator "CGF" de cada agente.
  • CalculateCenterPosition(): função interna que determina a posição central da população.
  • GlobalSearch(): função interna responsável pela busca global, explorando uma ampla região do espaço de soluções.
  • LocalSearch(): função interna responsável pela busca local, realizando uma exploração mais detalhada da região ao redor das soluções atuais.
  • SelectionPhase(): função interna que implementa a fase de seleção, escolhendo as melhores soluções para as etapas seguintes.
  • UpdateHeartMemory(): função interna que atualiza a "memória do coração" com as melhores soluções encontradas.
  • heartMemorySize: valor que define o número máximo de soluções armazenadas na "memória do coração".
  • heartMemory: array de objetos que representa a "memória do coração", no qual são armazenadas as melhores soluções encontradas.
  • tempPos: array de objetos temporários usado para armazenar novas posições ainda não avaliadas, principalmente durante a busca global.
  • cgf: array que armazena os valores de "CGF" de cada agente da população.
  • cgfCenter: valor escalar que representa o "CGF" do centro da população.
  • centerCoords: array que armazena as coordenadas do centro da população.
  • centerFitness: valor numérico que representa a qualidade (fitness) da posição central.
  • alpha: variável que representa um coeficiente associado à "angiogênese" (crescimento e desenvolvimento).
  • currentIteration: variável que acompanha o número da iteração (etapa) atual do algoritmo.
  • maxIterations: variável que define o número máximo de iterações que o algoritmo pode executar.
  • firstIteration: flag booleano que indica se a iteração atual é a primeira.
//————————————————————————————————————————————————————————————————————
class C_AO_ACCS : public C_AO
{
  public: //----------------------------------------------------------
  ~C_AO_ACCS () { }
  C_AO_ACCS ()
  {
    ao_name = "ACCS";
    ao_desc = "Artificial Coronary Circulation System";
    ao_link = "https://www.mql5.com/ru/articles/19861";

    popSize         = 50;    // population size (number of capillaries)
    bifurcationRate = 0.5;   // bifurcation coefficient

    ArrayResize (params, 2);

    params [0].name = "popSize";         params [0].val = popSize;
    params [1].name = "bifurcationRate"; params [1].val = bifurcationRate;
  }

  void SetParams ()
  {
    popSize         = (int)params [0].val;
    bifurcationRate = params      [1].val;
    
    // Heart Memory size: 25% of the population
    heartMemorySize = MathMax (1, (int)(popSize * 0.25));
  }

  bool Init (const double &rangeMinP  [],
             const double &rangeMaxP  [],
             const double &rangeStepP [],
             const int     epochsP);

  void Moving   ();
  void Revision ();

  private:
  void CalculateCGF ();
  void CalculateCenterPosition ();
  void GlobalSearch ();
  void LocalSearch ();
  void SelectionPhase ();
  void UpdateHeartMemory ();
  
  //------------------------------------------------------------------
  public:
  double bifurcationRate;   // bifurcation coefficient

  private: //---------------------------------------------------------
  int    heartMemorySize;       // Heart Memory size
  S_HeartMemory heartMemory []; // Heart Memory
  S_TempPosition tempPos [];    // Temporary positions for global search
  double cgf [];                // CGF array for each agent
  double cgfCenter;             // center CGF
  double centerCoords [];       // coordinates of the population center
  double centerFitness;         // center fitness
  double alpha;                 // current angiogenesis factor
  int    currentIteration;      // current iteration
  int    maxIterations;         // maximum number of iterations
  bool   firstIteration;        // first-iteration flag
};
//————————————————————————————————————————————————————————————————————

O método de inicialização "Init" da classe "C_AO_ACCS" prepara os parâmetros e as estruturas de dados antes da execução do algoritmo de otimização. Ele recebe os intervalos de busca das variáveis, os passos de variação e o número de épocas (iterações). O procedimento começa com a chamada da função padrão de inicialização, que verifica se os intervalos e os passos especificados estão corretos. Se essa verificação falhar, a inicialização será encerrada com erro.

Em seguida, o tamanho da "memória do coração" é definido como 25% do tamanho da população, com no mínimo um elemento. A partir desse valor, é criado um array de estruturas "Memória do coração", e em cada elemento são inicializadas as "coordenadas" (coords). Depois, é criado um array de posições temporárias com tamanho igual ao da população, destinado a armazenar as novas soluções que serão geradas na etapa seguinte. Cada elemento desse array também recebe seus parâmetros iniciais.

Também são inicializados os arrays destinados a armazenar os valores de CGF de cada agente e as coordenadas do centro da população. A sequência termina com a definição da iteração atual como zero, a atribuição do número máximo de iterações de acordo com os parâmetros de entrada, a definição do flag da primeira iteração como "true" e a atribuição do valor inicial ao fator de angiogênese ("alpha"). Assim, após a execução desse método, o algoritmo passa a dispor de todas as estruturas e parâmetros necessários para iniciar a otimização.

//————————————————————————————————————————————————————————————————————
//--- Initialization
bool C_AO_ACCS::Init (const double &rangeMinP  [],
                      const double &rangeMaxP  [],
                      const double &rangeStepP [],
                      const int     epochsP)
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;

  //------------------------------------------------------------------
  // Heart Memory size: 25% of the population
  heartMemorySize = MathMax (1, (int)(popSize * 0.25));
  
  // Initializing Heart Memory
  ArrayResize (heartMemory, heartMemorySize);
  for (int i = 0; i < heartMemorySize; i++)
  {
    heartMemory [i].Init (coords);
  }

  // Initializing temporary positions
  ArrayResize (tempPos, popSize);
  for (int i = 0; i < popSize; i++)
  {
    tempPos [i].Init (coords);
  }

  // Initializing arrays
  ArrayResize (cgf, popSize);
  ArrayResize (centerCoords, coords);
  
  currentIteration = 0;
  maxIterations = epochsP;
  firstIteration = true;
  alpha = 0.625;

  return true;
}
//————————————————————————————————————————————————————————————————————

O método "CalculateCGF" é destinado ao cálculo dos fatores de crescimento (CGF) de cada agente da população, permitindo avaliar sua contribuição para o desenvolvimento do sistema.

O procedimento começa com a determinação dos valores mínimo e máximo de fitness entre todas as soluções. Se todos os valores de fitness forem iguais, cada agente recebe o mesmo CGF, igual a 1 dividido pelo número total de agentes, garantindo que todos tenham a mesma influência. Caso os valores de fitness apresentem variação, o fitness de cada agente é normalizado com base nos valores mínimo e máximo, e um pequeno deslocamento é adicionado ao resultado para estabilizar os cálculos. Em seguida, é calculada a soma de todos os valores de fitness normalizados. O CGF de cada agente é então definido proporcionalmente ao seu fitness ajustado em relação a essa soma. O CGF do centro da população é calculado de forma análoga.

Esse método distribui de forma ponderada a influência de cada solução nas etapas seguintes do algoritmo, de acordo com sua qualidade.

//————————————————————————————————————————————————————————————————————
//--- Calculation of CGF (Coronary Growth Factor) according to Law 2
void C_AO_ACCS::CalculateCGF ()
{
  // For maximization: CGFi = fiti / Σfiti
  
  double minFit = DBL_MAX;
  double maxFit = -DBL_MAX;
  
  for (int i = 0; i < popSize; i++)
  {
    if (a [i].f < minFit) minFit = a [i].f;
    if (a [i].f > maxFit) maxFit = a [i].f;
  }
  
  double sumFitness = 0.0;
  
  // If all fitness values are the same
  if (MathAbs (maxFit - minFit) < 1e-10)
  {
    for (int i = 0; i < popSize; i++)
    {
      cgf [i] = 1.0 / popSize;
    }
    cgfCenter = 1.0 / popSize;
    return;
  }
  
  // Normalize the fitness values and calculate the sum
  for (int i = 0; i < popSize; i++)
  {
    double normalizedFit = (a [i].f - minFit) / (maxFit - minFit) + 0.1;
    sumFitness += normalizedFit;
  }
  
  // Calculate the CGF for each capillary
  for (int i = 0; i < popSize; i++)
  {
    double normalizedFit = (a [i].f - minFit) / (maxFit - minFit) + 0.1;
    cgf [i] = normalizedFit / sumFitness;
  }
  
  // CGF for the center
  double normalizedCenterFit = (centerFitness - minFit) / (maxFit - minFit) + 0.1;
  cgfCenter = normalizedCenterFit / sumFitness;
}
//————————————————————————————————————————————————————————————————————

O método "CalculateCenterPosition" calcula o centro da população com base nas coordenadas e no fitness. Primeiro, o array de coordenadas do centro e a variável usada para acumular o fitness são zerados. Em seguida, percorre-se toda a população, somando as coordenadas de cada solução para cada variável e acumulando também seus valores de fitness. Depois, as somas acumuladas são divididas pelo tamanho da população para obter os valores médios das coordenadas, que definem a posição do centro. O fitness médio é calculado da mesma forma, fornecendo uma estimativa da qualidade desse centro.

Esse método permite determinar o ponto central de toda a população, informação importante para os cálculos seguintes e para a geração de novas soluções.

//————————————————————————————————————————————————————————————————————
//--- Calculating the Central Position (Law 3)
void C_AO_ACCS::CalculateCenterPosition ()
{
  // Xc = mean(X), fitc = mean(fit)
  ArrayInitialize (centerCoords, 0.0);
  centerFitness = 0.0;
  
  for (int i = 0; i < popSize; i++)
  {
    for (int j = 0; j < coords; j++)
    {
      centerCoords [j] += a [i].c [j];
    }
    centerFitness += a [i].f;
  }
  
  for (int j = 0; j < coords; j++)
  {
    centerCoords [j] /= popSize;
  }
  centerFitness /= popSize;
}
//————————————————————————————————————————————————————————————————————

O método "GlobalSearch" implementa a busca global por novas posições das soluções, com o objetivo de promover o crescimento das artérias principais da população, com base na lei 4.

O procedimento começa percorrendo toda a população. Para cada solução, é selecionado aleatoriamente outro agente, exceto o agente atual. Em seguida, calcula-se um fator de bifurcação proporcional ao "CGF" do agente atual, que determina a magnitude do deslocamento. A direção da busca é definida pela comparação entre o "CGF" do agente atual e o do centro da população: se o primeiro for maior, o movimento segue uma direção; caso contrário, segue a direção oposta. Para cada coordenada, um novo valor é calculado por uma fórmula que depende da direção escolhida, do fator de bifurcação e de um número aleatório, introduzindo aleatoriedade nos deslocamentos e ampliando a diversidade das regiões exploradas. Depois disso, o novo valor da coordenada é verificado e, se necessário, ajustado pelo método "u.SeInDiSp" para permanecer dentro dos limites permitidos.

Esse método permite que a solução "cresça" e se desloque pelo espaço de busca, estimulando a exploração de novas regiões.

//————————————————————————————————————————————————————————————————————
//--- Global Search — Growth of Major Arteries (Law 4)
void C_AO_ACCS::GlobalSearch ()
{
  for (int i = 0; i < popSize; i++)
  {
    // Select a random capillary r (other than the current one)
    int r = i;
    while (r == i && popSize > 1)
    {
      r = (int)MathFloor (u.RNDfromCI (0.0, popSize - 0.001));
      if (r >= popSize) r = popSize - 1;
      if (r < 0) r = 0;
    }
    
    // Bifurcation factor Bf = CGFi
    double Bf = cgf [i] * bifurcationRate;
    
    // Determine the direction based on the CGF comparison
    double dir;
    if (cgfCenter < cgf [i])  // According to the document
    {
      dir = -1.0;
    }
    else
    {
      dir = 1.0;
    }
    
    // Apply the Law 4 formula
    for (int j = 0; j < coords; j++)
    {
      double rand_val = u.RNDfromCI (0.0, 1.0);
      
      // X^(t+1)_i,j = X^t_r,j + dir × Bf × (X^t_c,j - rand × X^t_r,j)
      tempPos [i].coords [j] = a [r].c [j] + dir * Bf * (centerCoords [j] - rand_val * a [r].c [j]);
      
      // Check bounds
      tempPos [i].coords [j] = u.SeInDiSp (tempPos [i].coords [j], rangeMin [j], rangeMax [j], rangeStep [j]);
    }
  }
}
//————————————————————————————————————————————————————————————————————

O método "LocalSearsh" implementa a busca local voltada ao desenvolvimento dos capilares no algoritmo. O procedimento começa com a atualização do fator de crescimento dos capilares, que depende da iteração atual e do número máximo de iterações: quanto mais iterações tiverem sido concluídas, maior será o valor desse fator. Em seguida, são identificadas a melhor e a pior solução da população atual, que servirão de referência para o ajuste local.

Para cada solução e cada coordenada, uma nova posição é calculada sucessivamente com um deslocamento baseado na diferença entre as coordenadas da melhor e da pior solução, levando em conta um peso aleatório e o fator de crescimento. Após o cálculo, o novo valor é verificado e, se necessário, ajustado pelo método "u.SeInDiSp" para permanecer dentro do intervalo permitido. Esse procedimento contribui para aprimorar as soluções na região local de busca, melhorando sua qualidade e aproximando-as do ótimo.

//————————————————————————————————————————————————————————————————————
//--- Local Search - Capillary Growth (Law 6)
void C_AO_ACCS::LocalSearch ()
{
  // Update the angiogenesis factor: α = 0.625 × √(itr/itrmax)
  if (maxIterations > 0 && currentIteration > 0)
  {
    alpha = 0.625 * MathSqrt ((double)currentIteration / (double)maxIterations);
  }
  else
  {
    alpha = 0.625;
  }
  
  // Find the best and worst positions in the current population
  int bestIdx = 0, worstIdx = 0;
  
  for (int i = 1; i < popSize; i++)
  {
    if (a [i].f > a [bestIdx].f) bestIdx = i;
    if (a [i].f < a [worstIdx].f) worstIdx = i;
  }
  
  // Apply local search (Law 6)
  for (int i = 0; i < popSize; i++)
  {
    for (int j = 0; j < coords; j++)
    {
      double rand_val = u.RNDfromCI (0.0, 1.0);
      
      // X^(t+1)_i,j = X^t_i,j + α × rand × (X^t_b,j - X^t_w,j)
      a [i].c [j] = a [i].c [j] + alpha * rand_val * (a [bestIdx].c [j] - a [worstIdx].c [j]);
      
      // Check bounds
      a [i].c [j] = u.SeInDiSp (a [i].c [j], rangeMin [j], rangeMax [j], rangeStep [j]);
    }
  }
}
//————————————————————————————————————————————————————————————————————

O método "SelectionPhase" implementa a fase de seleção, na qual as soluções atuais são atualizadas com base nos resultados da busca global. Para cada elemento da população, as coordenadas atuais são substituídas pelas novas coordenadas obtidas anteriormente durante a busca global. Isso é feito copiando as novas posições dos arrays temporários para os arrays principais das soluções. Dessa forma, a fase de seleção realiza a transição para novas soluções potencialmente mais eficientes, preparando a população para a etapa seguinte do algoritmo.

//————————————————————————————————————————————————————————————————————
//--- Selection Phase (Law 5)
void C_AO_ACCS::SelectionPhase ()
{
  // Apply new positions from the global search
  for (int i = 0; i < popSize; i++)
  {
    // Copy the new position
    ArrayCopy (a [i].c, tempPos [i].coords, 0, 0, coords);
  }
}
//————————————————————————————————————————————————————————————————————

O método "UpdateHeartMemory" atualiza a memória do coração do algoritmo, funcionando como um mecanismo para preservar as melhores soluções encontradas. Para isso, todas as soluções atuais são ordenadas por seu valor da função de avaliação (fitness), em ordem decrescente, de modo que as melhores fiquem no início. Após a ordenação, é selecionado o número predefinido de melhores soluções, e suas coordenadas, juntamente com os respectivos valores de fitness, são armazenadas em uma memória específica.

Esse procedimento permite preservar as melhores soluções e utilizá-las posteriormente para orientar a busca, mantendo o equilíbrio entre diversificação e intensificação no espaço de soluções.

//————————————————————————————————————————————————————————————————————
//--- Updating Heart Memory (Law 7)
void C_AO_ACCS::UpdateHeartMemory ()
{
  // Create a temporary array for sorting
  struct S_IndexedAgent
  {
    int index;
    double fitness;
  };
  
  S_IndexedAgent indexed [];
  ArrayResize (indexed, popSize);
  
  for (int i = 0; i < popSize; i++)
  {
    indexed [i].index = i;
    indexed [i].fitness = a [i].f;
  }
  
  // Bubble sort in descending order of fitness
  for (int i = 0; i < popSize - 1; i++)
  {
    for (int j = i + 1; j < popSize; j++)
    {
      if (indexed [j].fitness > indexed [i].fitness)
      {
        S_IndexedAgent temp = indexed [i];
        indexed [i] = indexed [j];
        indexed [j] = temp;
      }
    }
  }
  
  // Store the best solutions in Heart Memory
  for (int i = 0; i < heartMemorySize; i++)
  {
    int idx = indexed [i].index;
    ArrayCopy (heartMemory [i].position, a [idx].c, 0, 0, coords);
    heartMemory [i].fitness = a [idx].f;
  }
}
//————————————————————————————————————————————————————————————————————

A etapa principal do método "Moving" do algoritmo consiste na execução sequencial de várias fases fundamentais. Inicialmente, é feita a inicialização da população, com a geração aleatória das soluções iniciais dentro dos intervalos permitidos e de acordo com os passos definidos. Essa inicialização é realizada apenas uma vez, antes do início das demais iterações. Depois disso, o contador interno de iterações é atualizado.

Em seguida, o algoritmo calcula a posição central, que serve como referência para a busca. Depois, é calculado o fator de crescimento coronariano dos capilares (CGF), que ajuda a determinar a importância e a contribuição de cada elemento. Na sequência, é executada a busca global por novas soluções com base nos dados obtidos, ampliando a região explorada do espaço de busca. Ao final de cada ciclo, ocorre a fase de seleção, na qual as soluções atuais são substituídas pelas novas soluções obtidas durante a busca. Esse ciclo se repete para promover o aprimoramento gradual das soluções.

//————————————————————————————————————————————————————————————————————
//--- Main step of the algorithm
void C_AO_ACCS::Moving ()
{
  // Population Initialization (Law 1)
  if (!revision)
  {
    for (int i = 0; i < popSize; i++)
    {
      for (int j = 0; j < coords; j++)
      {
        a [i].c [j] = u.RNDfromCI (rangeMin [j], rangeMax [j]);
        a [i].c [j] = u.SeInDiSp (a [i].c [j], rangeMin [j], rangeMax [j], rangeStep [j]);
      }
    }
    
    revision = true;
    firstIteration = true;
    currentIteration = 0;
    return;
  }
  
  currentIteration++;
  
  // Calculating the Central Position (Law 3)
  CalculateCenterPosition ();
  
  // Calculate CGF for all capillaries (Law 2)
  CalculateCGF ();
  
  // Perform global search (Law 4)
  GlobalSearch ();
  
  // Apply selection (Law 5)
  SelectionPhase ();
}
//————————————————————————————————————————————————————————————————————

O método "Revision" é responsável por verificar as soluções atuais e atualizar seus dados para uso posterior no algoritmo.

Na primeira iteração, são inicializadas as melhores posições individuais de cada agente e também é armazenada a melhor solução de toda a população, permitindo preservar as soluções de melhor desempenho. Em seguida, para cada indivíduo, sua posição atual e o valor da função de avaliação são salvos como valores anteriores. Depois disso, as novas soluções são comparadas com as respectivas melhores soluções individuais: se a nova posição for pior, há uma probabilidade de retorno à melhor posição individual (poda), o que ajuda a evitar a deterioração dos resultados. Se a solução tiver melhorado, ela passa a ser a nova melhor posição individual.

Na sequência, é executada a busca local para aprimorar as soluções, a memória do coração é atualizada pelo método correspondente e, por fim, a melhor solução global de toda a população é verificada e atualizada.

//————————————————————————————————————————————————————————————————————
//--- Checking and Updating Results
void C_AO_ACCS::Revision ()
{
  if (firstIteration)
  {
    firstIteration = false;
    // Initialize personal best positions
    for (int i = 0; i < popSize; i++)
    {
      a [i].fB = a [i].f;
      ArrayCopy (a [i].cB, a [i].c, 0, 0, coords);
    }
    // Initialize the Heart Memory
    UpdateHeartMemory ();
  }
  
  // Save previous positions and fitness values
  for (int i = 0; i < popSize; i++)
  {
    ArrayCopy (a [i].cP, a [i].c, 0, 0, coords);
    a [i].fP = a [i].f;
  }
  
  // After evaluating the fitness of new positions from the global search,
  // check for improvement (Law 5: selection and pruning)
  for (int i = 0; i < popSize; i++)
  {
    // If the new position is worse than this agent's previous best position
    if (a [i].f < a [i].fB)
    {
      // Pruning probability
      double pruningProb = 0.2;
      if (u.RNDfromCI (0.0, 1.0) < pruningProb)
      {
        // Pruning—return to the personal best position
        ArrayCopy (a [i].c, a [i].cB, 0, 0, coords);
        a [i].f = a [i].fB;
      }
    }
    else
    {
      // Update the agent's personal best solution
      a [i].fB = a [i].f;
      ArrayCopy (a [i].cB, a [i].c, 0, 0, coords);
    }
  }
  
  // Perform local search (Law 6)
  LocalSearch ();
  
  // Update Heart Memory (Law 7)
  UpdateHeartMemory ();
  
  // Update the global best solution
  for (int i = 0; i < popSize; i++)
  {
    if (a [i].f > fB)
    {
      fB = a [i].f;
      ArrayCopy (cB, a [i].c, 0, 0, WHOLE_ARRAY);
    }
  }
}
//————————————————————————————————————————————————————————————————————


Resultados dos testes

Os resultados dos testes são, para dizer o mínimo, fracos. Mas há um grande "PORÉM", que veremos mais adiante.

ACCS|Artificial Coronary Circulation System|50.0|0.5|
=============================
5 Hilly's; Func runs: 10000; result: 0.5388483416731469
25 Hilly's; Func runs: 10000; result: 0.40315510603699484
500 Hilly's; Func runs: 10000; result: 0.2750619992528315
=============================
5 Forest's; Func runs: 10000; result: 0.4373687177939665
25 Forest's; Func runs: 10000; result: 0.24807871438181
500 Forest's; Func runs: 10000; result: 0.17536977563388764
=============================
5 Megacity's; Func runs: 10000; result: 0.3692307692307693
25 Megacity's; Func runs: 10000; result: 0.2116923076923077
500 Megacity's; Func runs: 10000; result: 0.10640000000000094
=============================
All score: 2.76521 (30.72%)

Vamos executar o script de teste com o algoritmo. O que chama a atenção logo de início é que o padrão de movimento dos agentes no espaço de busca muda bastante conforme as características da superfície da função analisada, o que, por si só, é uma característica marcante de algoritmos de otimização que merecem uma análise mais atenta.

Hilly

ACCS na função de teste Hilly

Forest

ACCS na função de teste Forest

Megacity

ACCS na função de teste Megacity

O mecanismo de busca global baseado no movimento em relação ao centro da população, levando em conta a direção, mostra-se bastante eficiente para determinados tipos de problemas em que os extremos estão exatamente no centro da função. O algoritmo resolve esses casos com facilidade porque sua estratégia de busca se baseia no cálculo da posição média da população; essa simples coincidência lhe proporciona uma vantagem na busca. Por isso, para avaliar o algoritmo de forma "justa", são necessárias funções de teste que imponham desafios menos triviais.

Em funções padrão desse tipo, o algoritmo "se sai" muito bem. No entanto, o cenário se inverte completamente quando o algoritmo se depara com paisagens mais complexas, como as de nossas funções de teste apresentadas acima. Há ainda outra hipótese, que precisa ser verificada: a excelente convergência nessas funções com extremo no centro pode estar relacionada ao fato de essas funções apresentarem simetria em dois planos.

Paraboloid

ACCS na função de teste padrão Paraboloid

Acley

ACCS na função de teste padrão Ackley

Rastrigin

ACCS na  função de teste padrão Rastrigin

Na tabela de classificação, o algoritmo ACCS é apresentado apenas para fins de referência.

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 DOAdingom dingo_optimization_algorithm_M 0,47968 0,45367 0,46369 1,39704 0,94145 0,87909 0,91454 2,73508 0,78615 0,86061 0,84805 2,49481 6,627 73,63
2 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
3 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
4 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
5 (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
6 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
7 TETA time evolution travel algorithm (joo) 0,91362 0,82349 0,31990 2,05701 0,97096 0,89532 0,29324 2,15952 0,73462 0,68569 0,16021 1,58052 5,797 64,41
8 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
9 BOAm billiards optimization algorithm M 0,95757 0,82599 0,25235 2,03590 1,00000 0,90036 0,30502 2,20538 0,73538 0,52523 0,09563 1,35625 5,598 62,19
10 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
11 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
12 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
13 EOm extremal_optimization_M 0,76166 0,77242 0,31747 1,85155 0,99999 0,76751 0,23527 2,00277 0,74769 0,53969 0,14249 1,42987 5,284 58,71
14 BBO biogeography based optimization 0,94912 0,69456 0,35031 1,99399 0,93820 0,67365 0,25682 1,86867 0,74615 0,48277 0,17369 1,40261 5,265 58,50
15 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
16 DA dialectical algorithm 0,86183 0,70033 0,33724 1,89940 0,98163 0,72772 0,28718 1,99653 0,70308 0,45292 0,16367 1,31967 5,216 57,95
17 BHAm black hole algorithm M 0,75236 0,76675 0,34583 1,86493 0,93593 0,80152 0,27177 2,00923 0,65077 0,51646 0,15472 1,32195 5,196 57,73
18 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
19 RFO royal flush optimization (joo) 0,83361 0,73742 0,34629 1,91733 0,89424 0,73824 0,24098 1,87346 0,63154 0,50292 0,16421 1,29867 5,089 56,55
20 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
21 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
22 BSA backtracking_search_algorithm 0,97309 0,54534 0,29098 1,80941 0,99999 0,58543 0,21747 1,80289 0,84769 0,36953 0,12978 1,34700 4,959 55,10
23 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
24 SRA successful restaurateur algorithm (joo) 0,96883 0,63455 0,29217 1,89555 0,94637 0,55506 0,19124 1,69267 0,74923 0,44031 0,12526 1,31480 4,903 54,48
25 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
26 BIO blood inheritance optimization (joo) 0,81568 0,65336 0,30877 1,77781 0,89937 0,65319 0,21760 1,77016 0,67846 0,47631 0,13902 1,29378 4,842 53,80
27 DOA dream_optimization_algorithm 0,85556 0,70085 0,37280 1,92921 0,73421 0,48905 0,24147 1,46473 0,77231 0,47354 0,18561 1,43146 4,825 53,62
28 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
29 DEA dolphin_echolocation_algorithm 0,75995 0,67572 0,34171 1,77738 0,89582 0,64223 0,23941 1,77746 0,61538 0,44031 0,15115 1,20684 4,762 52,91
30 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
31 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
32 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
33 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
34 (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
35 FBA fractal-based Algorithm 0,79000 0,65134 0,28965 1,73099 0,87158 0,56823 0,18877 1,62858 0,61077 0,46062 0,12398 1,19537 4,555 50,61
36 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
37 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
38 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
39 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
40 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
41 CAm camel algorithm M 0,78684 0,56042 0,35133 1,69859 0,82772 0,56041 0,24336 1,63149 0,64846 0,33092 0,13418 1,11356 4,444 49,37
42 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
43 CMAES covariance_matrix_adaptation_evolution_strategy 0,76258 0,72089 0,00000 1,48347 0,82056 0,79616 0,00000 1,61672 0,75846 0,49077 0,00000 1,24923 4,349 48,33
44 DA_duelist duelist_algorithm 0,92782 0,53778 0,27792 1,74352 0,86957 0,47536 0,18193 1,52686 0,62153 0,33569 0,11715 1,07437 4,345 48,28
45 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
ACCS artificial_coronary_circulation_system 0,53885 0,40316 0,27507 1,21708 0,43737 0,24807 0,17537 0,86081 0,36923 0,21169 0,10640 0,68732 2,765 30,72
RW random walk 0,48754 0,32159 0,25781 1,06694 0,37554 0,21944 0,15877 0,75375 0,27969 0,14917 0,09847 0,52734 2,348 26,09


Conclusões

O algoritmo ACCS representa uma tentativa interessante de aplicar o modelo biológico de crescimento das artérias coronárias a problemas de otimização. No entanto, sua implementação prática revelou limitações significativas. O resultado de 30% do máximo possível aponta para problemas fundamentais no funcionamento do algoritmo, que o impedem de competir com os melhores métodos de otimização. Sua principal fraqueza está na dependência excessiva da distribuição atual da população por meio do mecanismo "CGF", o que leva à convergência prematura e à diversificação insuficiente no espaço de busca.

O mecanismo de busca global baseado no movimento em relação ao centro da população, com a direção determinada pela comparação dos valores de "CGF", mostra-se pouco eficiente para escapar de ótimos locais, sobretudo em paisagens multimodais complexas. A busca local, baseada no movimento entre a melhor e a pior solução com um fator de angiogênese decrescente, talvez seja simplificada demais e não leve em conta a topologia do espaço de busca.

A memória do coração, que armazena 25% das melhores soluções, na prática reproduz o papel do elitismo, mas não é utilizada ativamente para orientar a busca, tornando-se mais um arquivo passivo do que um componente ativo do algoritmo. Embora conceitualmente atraente, a metáfora biológica não se traduz em mecanismos computacionais eficientes: em um sistema biológico real, o crescimento das artérias, a bifurcação e a poda são controlados por complexos gradientes químicos e tensões mecânicas, difíceis de modelar adequadamente por meio de fórmulas matemáticas simples.

A tentativa de combinar a busca global e a busca local por meio da aplicação sequencial de duas estratégias distintas de movimento acaba gerando um conflito entre diversificação e intensificação, em vez de produzir sinergia entre elas. Testei várias versões do algoritmo com pequenas alterações na ordem das estratégias de busca e em sua implementação, procurando não me afastar da ideia original, mas isso não trouxe melhorias significativas. Por isso, deixo tudo como está. Para quem gosta de experimentar, estão à disposição todas as ferramentas e condições necessárias para tentar melhorar os resultados. Além disso, permanece em aberto a questão das razões para a alta eficiência observada em alguns problemas no contexto deste artigo.

tab

Figura 3. Graduação de cores dos algoritmos nos respectivos testes

chart

Figura 4. Histograma dos resultados dos testes dos algoritmos (em uma escala de 0 a 100, quanto maior, melhor, em que 100 é o resultado teórico máximo possível; no arquivo compactado há um script para calcular a tabela de classificação)

Vantagens e pontos fracos do algoritmo ACCS:

Vantagens:

  1. Poucos parâmetros externos.
  2. Extremamente eficiente em determinados tipos de problemas, inclusive em problemas de alta dimensionalidade.

Pontos fracos:

  1. Convergência fraca em paisagens complexas.

Foi 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 sua capacidade de busca. As conclusões e avaliações apresentadas nos artigos baseiam-se nos resultados dos experimentos realizados.


Programas utilizados no artigo

# Nome Tipo Descrição
1 #C_AO.mqh
Arquivo de inclusão
Classe base dos algoritmos populacionais de otimização
2 #C_AO_enum.mqh
Arquivo de inclusão
Enumeração dos algoritmos populacionais de otimização
3 TestFunctions.mqh
Arquivo de inclusão
Biblioteca de funções de teste
4
TestStandFunctions.mqh
Arquivo de inclusão
Biblioteca de funções da bancada de testes
5
Utilities.mqh
Arquivo de inclusão
Biblioteca de funções auxiliares
6
CalculationTestResults.mqh
Arquivo de inclusão
Script para calcular os resultados da 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_ACCS.mq5
Script Bancada de testes do ACCS

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

Arquivos anexados |
ACCS.zip (286.72 KB)
Redes neurais em trading: abordagem semântica baseada em spikes para identificação espaço-temporal (Componentes principais) Redes neurais em trading: abordagem semântica baseada em spikes para identificação espaço-temporal (Componentes principais)
Neste artigo, analisamos em detalhes a integração do módulo SSAM ao bloco SEW-ResNeXt, mostrando como o framework S3CE-Net permite combinar de forma eficiente a atenção baseada em spikes com blocos residuais. Essa arquitetura proporciona um processamento preciso dos fluxos de dados temporais e espaciais, além de alta estabilidade durante o treinamento. A modularidade e a flexibilidade dos componentes facilitam a expansão do modelo e a reutilização de métodos já validados.
Mapas auto-organizáveis de Kohonen em um EA MQL5 Mapas auto-organizáveis de Kohonen em um EA MQL5
Os mapas auto-organizáveis de Kohonen transformam o caos dos dados de mercado em um mapa bidimensional estruturado, no qual padrões semelhantes são agrupados. Este artigo apresenta uma implementação completa de SOM em um EA MQL5, com quatrocentos neurônios e treinamento contínuo. Analisamos o algoritmo de busca pela Best Matching Unit, a atualização dos pesos com uma função gaussiana de vizinhança, a integração com efeitos quânticos e a geração de sinais de trading. O código é aberto, a matemática é clara e os resultados podem ser verificados.
Análise da influência dos ciclos solares e lunares sobre os preços das moedas Análise da influência dos ciclos solares e lunares sobre os preços das moedas
E se os ciclos lunares e os padrões sazonais influenciarem os mercados cambiais? Este artigo mostra como traduzir conceitos astrológicos para a linguagem da matemática e do machine learning. Criei um sistema em Python com 88 atributos baseados em ciclos astronômicos, treinei o CatBoost com 15 anos de dados do EUR/USD e obtive resultados intrigantes. O código é aberto, os métodos podem ser verificados e as conclusões são inesperadas: a sabedoria antiga encontra o gradient boosting.
Redes neurais em trading: Abordagem semântica baseada em spikes para identificação espaço-temporal (S3CE-Net) Redes neurais em trading: Abordagem semântica baseada em spikes para identificação espaço-temporal (S3CE-Net)
Apresentamos o framework S3CE-Net e seus mecanismos SSAM e STFS, que processam com precisão eventos de spikes levando em conta a causalidade. O modelo é leve, opera em paralelo e é capaz de identificar relações complexas no tempo e no espaço.