Algoritmo de sistema artificial de circulação coronariana (Artificial Coronary Circulation System, ACCS)
Conteúdo
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.

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.
-
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
-
-
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
-
-
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)
-
-
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).
-
-
-
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)
-
-
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
-
-
Critério de parada
-
O número máximo de iterações foi atingido
-
Vamos observar a seguir o esquema de funcionamento do algoritmo.

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.

ACCS na função de teste Hilly

ACCS na função de teste Forest

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.

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

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

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.

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

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:
- Poucos parâmetros externos.
- Extremamente eficiente em determinados tipos de problemas, inclusive em problemas de alta dimensionalidade.
Pontos fracos:
- 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
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Redes neurais em trading: abordagem semântica baseada em spikes para identificação espaço-temporal (Componentes principais)
Mapas auto-organizáveis de Kohonen em um EA MQL5
Análise da influência dos ciclos solares e lunares sobre os preços das moedas
Redes neurais em trading: Abordagem semântica baseada em spikes para identificação espaço-temporal (S3CE-Net)
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso