
Algoritmo de busca orbital atômica — Atomic Orbital Search (AOS): Modificação
Conteúdo
- Introdução
- Implementação do algoritmo
- Exemplo de uso dos algoritmos da classe C_AO
- Resultados dos testes
Introdução
Na primeira parte do artigo, examinamos em detalhes o algoritmo AOS (Atomic Orbital Search), seus fundamentos inspirados no modelo orbital atômico e os mecanismos que sustentam seu funcionamento. Discutimos como o algoritmo utiliza distribuições probabilísticas e a dinâmica das interações para buscar soluções ótimas em problemas de otimização complexos.
Na segunda parte do artigo, focaremos na modificação do algoritmo AOS, pois não podemos ignorar uma ideia tão notável sem buscar aprimorá-la. Analisaremos o conceito de melhoria do algoritmo, com especial atenção para os operadores específicos que pertencem a este método e que podem aumentar sua eficiência e adaptabilidade.
Trabalhar no algoritmo AOS abriu para mim muitos aspectos interessantes relacionados aos seus métodos de busca no espaço de soluções. Durante a pesquisa, também cheguei a várias ideias sobre como melhorar esse algoritmo interessante. Em particular, concentrei-me na reformulação dos métodos existentes que podem melhorar o desempenho do algoritmo, aprimorando sua capacidade de explorar espaços de soluções complexos. Veremos como essas melhorias podem ser integradas à estrutura existente do algoritmo AOS, tornando-o uma ferramenta ainda mais poderosa para resolver problemas de otimização. Assim, nosso objetivo é não apenas analisar os mecanismos existentes, mas também propor novas abordagens que podem ampliar significativamente as capacidades do algoritmo AOS.
Implementação do algoritmo
No artigo anterior, examinamos em detalhes os componentes-chave do algoritmo AOS. Lembramos que neste algoritmo a população é considerada como uma molécula, e a área admissível de coordenadas, onde ocorre a busca por soluções ótimas, é representada como um átomo. Cada átomo é composto por diferentes camadas, que ajudam a organizar e direcionar a busca.
Os valores específicos obtidos em cada coordenada no processo de otimização podem ser interpretados como elétrons. Esses elétrons, localizados dentro do átomo, representam possíveis soluções para um dos parâmetros do problema em questão. Assim, cada molécula (população) busca encontrar os valores ótimos (elétrons) dentro da área definida (átomo).
Na versão original do algoritmo AOS, a energia da camada BEk é definida como a média aritmética da energia dos elétrons na camada, e a ligação BSk é definida como a média aritmética de suas coordenadas. A energia BEk é usada para comparar com a energia dos elétrons, a fim de determinar a maneira de seu deslocamento subsequente. A ligação BSk serve para calcular o incremento na posição dos elétrons, ou seja, a diferença entre a melhor posição dos elétrons, LEk, na camada, e a ligação BSk, pela seguinte fórmula: Xki[t+1] = Xkit + αi × (βi × LEk − γi × BSk).
Proponho abandonar a posição média dos elétrons BSk em favor da melhor posição individual de cada um. Dessa forma, o elétron se moverá em direção à melhor solução em sua camada, com base em seu próprio desempenho, e não em uma solução média da camada. Além disso, os dois componentes aleatórios βi e γi parecem ser redundantes, já que já existe um componente aleatório externo αi. Isso permitirá reduzir o tempo de geração de números aleatórios nesta fórmula em três vezes, sem que o sentido físico seja perdido.
Agora vamos analisar a estrutura que descreve a camada no átomo. Vermelho são destacados os elementos que serão removidos do código://—————————————————————————————————————————————————————————————————————————————— struct S_Layer { int pc; // счетчик частиц double BSk; // состояние связи double BEk; // энергия связи double LEk; // минимальная энергия void Init () { pc = 0; BSk = 0.0; BEk = 0.0; LEk = 0.0; } }; //——————————————————————————————————————————————————————————————————————————————
Vamos analisar o código do método "CalcLayerParams", responsável pelo cálculo das características das camadas, como energia e ligação. As linhas destacadas em vermelho serão removidas, pois não serão mais necessárias. Lembramos que este método desempenha um papel fundamental na estratégia de busca do AOS, voltada para evitar que o algoritmo fique preso em armadilhas locais. Como o nível de energia nas camadas não depende de sua localização (a energia diminui do centro para as camadas externas do átomo), mas é determinado pela presença de extremos locais significativos (a camada externa pode ter energia superior às internas), as camadas servem para ajustar o movimento dos elétrons no espaço de busca.
A quantidade aleatória de camadas a cada época ajuda a combater o aprisionamento do algoritmo em armadilhas locais, impedindo que os elétrons fiquem presos apenas em uma camada. Na versão modificada, também não será mais necessário calcular a energia média de todo o átomo, portanto removeremos as linhas correspondentes.
Figura 1. Diferenças na direção e no tamanho do deslocamento do elétron e em função da quantidade de camadas no átomo
A Figura 1 ilustra as diferenças no comportamento dos elétrons em átomos com diferentes quantidades de camadas no algoritmo AOS. A parte superior mostra um átomo com três camadas, no qual o elétron está na camada L1 com o valor da função objetivo B1 e se move em direção ao melhor valor local LEk1. A parte inferior da figura ilustra um átomo com duas camadas, onde o elétron também está na camada L1 e se move em direção ao melhor valor local LEk1, com o valor da função objetivo B1 (no caso de três camadas, esse seria o ponto LEk2).
Elementos-chave na figura:
- B0, B1, B2 — designações dos valores locais da função objetivo para as respectivas camadas,
- LEk0, LEk1, LEk2 — melhores soluções nas respectivas camadas,
- L0, L1, L2 — camadas no átomo,
- e — elétron,
- MIN, MAX — limites das camadas externas dos átomos (condições de fronteira para os parâmetros do problema de otimização).
//—————————————————————————————————————————————————————————————————————————————— // Расчет параметров для каждого слоя void C_AO_AOS::CalcLayerParams () { double energy; // Обработка каждой координаты (атома) for (int c = 0; c < coords; c++) { atoms [c].Init (maxLayers); // Обработка каждого слоя for (int L = 0; L < currentLayers [c]; L++) { energy = -DBL_MAX; // Обработка каждого электрона for (int e = 0; e < popSize; e++) { if (electrons [e].layerID [c] == L) { atoms [c].layers [L].pc++; atoms [c].layers [L].BEk += a [e].f; atoms [c].layers [L].BSk += a [e].c [c]; if (a [e].f > energy) { energy = a [e].f; atoms [c].layers [L].LEk = a [e].c [c]; } } } // Расчет средних значений для слоя if (atoms [c].layers [L].pc != 0) { atoms [c].layers [L].BEk /= atoms [c].layers [L].pc; atoms [c].layers [L].BSk /= atoms [c].layers [L].pc; } } } // Расчет общего состояния связей ArrayInitialize (BS, 0); for (int c = 0; c < coords; c++) { for (int e = 0; e < popSize; e++) { BS [c] += a [e].c [c]; } BS [c] /= popSize; } } //——————————————————————————————————————————————————————————————————————————————
Para atualizar as melhores soluções individuais, adicionaremos código ao método "Revision" na classe da versão modificada "C_AO_AOSm".
//—————————————————————————————————————————————————————————————————————————————— // Метод пересмотра лучших решений void C_AO_AOSm::Revision () { int bestIndex = -1; // Поиск лучшего решения в текущей итерации for (int i = 0; i < popSize; i++) { // Обновление глобального лучшего решения if (a [i].f > fB) { fB = a [i].f; bestIndex = i; } // Обновление персонального лучшего решения if (a [i].f > a [i].fB) { a [i].fB = a [i].f; ArrayCopy (a [i].cB, a [i].c, 0, 0, WHOLE_ARRAY); } } // Обновление лучших координат если найдено лучшее решение if (bestIndex != -1) ArrayCopy (cB, a [bestIndex].c, 0, 0, WHOLE_ARRAY); } //——————————————————————————————————————————————————————————————————————————————
No método "UpdateElectrons", removeremos as variáveis "β" e "γ", pois elas não serão mais necessárias para gerar os números aleatórios correspondentes. Além disso, eliminaremos a divisão do incremento do elétron pelo número de camadas no caso de movimento em direção à solução global. Para ser sincero, a decisão dos autores parece discutível, e o sentido físico dessa abordagem não é totalmente claro. Talvez os autores quisessem tornar a intensidade do movimento dos elétrons em direção à solução global variável, mudando-a de acordo com o número de camadas: quanto menos camadas, mais intenso deveria ser o movimento (embora meus experimentos tenham mostrado que isso não traz benefício algum).
//—————————————————————————————————————————————————————————————————————————————— // Обновление положения электронов void C_AO_AOS::UpdateElectrons () { double α; // коэффициент скорости double β; // коэффициент веса лучшего решения double γ; // коэффициент веса среднего состояния double φ; // вероятность перехода double newPos; // новая позиция double LE; // лучшая энергия double BSk; // состояние связи int lID; // идентификатор слоя // Обработка каждой частицы for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { φ = u.RNDprobab (); if (φ < PR) { // Случайное рассеивание newPos = u.RNDfromCI (rangeMin [c], rangeMax [c]); } else { lID = electrons [p].layerID [c]; α = u.RNDfromCI (-1.0, 1.0); β = u.RNDprobab (); γ = u.RNDprobab (); // Если текущая энергия частицы меньше средней энергии слоя if (a [p].f < atoms [c].layers [lID].BEk) { // Движение в сторону глобального оптимума---------------------------- LE = cB [c]; newPos = a [p].c [c]+ α * (β * LE - γ * BS [c]) / currentLayers [c]; } else { // Движение в сторону локального оптимума слоя------------------------ LE = atoms [c].layers [lID].LEk; BSk = atoms [c].layers [lID].BSk; newPos = a [p].c [c] + α * (β * LE - γ * BSk); } } // Ограничение новой позиции в пределах диапазона поиска с учетом шага a [p].c [c] = u.SeInDiSp (newPos, rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————
Adicionalmente, no método "UpdateElectrons" da classe "C_AO_AOSm", em vez de espalhar aleatoriamente o elétron pelo espaço de busca, implementaremos o movimento do elétron para o centro do núcleo com certa probabilidade. Na prática, isso significa substituir o valor de alguma coordenada pelo valor da solução global, o que deve melhorar as propriedades combinatórias do algoritmo. Já a dispersão aleatória era destinada a proporcionar diversidade na população de soluções, mas essa propriedade acabava promovendo a propagação dos elétrons conforme uma distribuição lognormal, onde havia uma probabilidade diferente de zero de o elétron atingir qualquer ponto do espaço durante o movimento.
Verde são indicadas as mudanças nas fórmulas de movimentação dos elétrons, agora o incremento é calculado como a diferença entre a melhor solução local da camada e a melhor solução individual do elétron.
//—————————————————————————————————————————————————————————————————————————————— // Обновление положения электронов void C_AO_AOSm::UpdateElectrons () { double α; // коэффициент скорости double φ; // вероятность перехода double newPos; // новая позиция double LE; // лучшая энергия double BSk; // состояние связи int lID; // идентификатор слоя // Обработка каждой частицы for (int p = 0; p < popSize; p++) { for (int c = 0; c < coords; c++) { φ = u.RNDprobab (); if (φ < PR) { // Случайный переход к центру newPos = cB [c]; } else { lID = electrons [p].layerID [c]; α = u.RNDfromCI (-1.0, 1.0); // Если текущая энергия частицы меньше средней энергии слоя if (a [p].f < atoms [c].layers [lID].BEk) { // Движение в сторону глобального оптимума---------------------------- LE = cB [c]; newPos = a [p].cB [c]+ α * (LE - a [p].cB [c]); } else { // Движение в сторону локального оптимума слоя------------------------ LE = atoms [c].layers [lID].LEk; newPos = a [p].cB [c]+ α * (LE - a [p].cB [c]); } } // Ограничение новой позиции в пределах диапазона поиска с учетом шага a [p].c [c] = u.SeInDiSp (newPos, rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————
O método "DistributeParticles" distribui os elétrons no espaço de busca, utilizando uma distribuição lognormal para cada coordenada. Para cada partícula e cada coordenada, é chamada uma função que gera a posição considerando os parâmetros definidos (valor médio, mínimo e máximo, pico), e depois é aplicada uma função adicional para ajustar a posição dentro do intervalo especificado.
//—————————————————————————————————————————————————————————————————————————————— // Распределение частиц в пространстве поиска void C_AO_AOS::DistributeParticles () { for (int i = 0; i < popSize; i++) { for (int c = 0; c < coords; c++) { // Используем логнормальное распределение для позиционирования частиц a [i].c [c] = u.LognormalDistribution (cB [c], rangeMin [c], rangeMax [c], peakPosition); a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————
Vamos alterar a distribuição dos elétrons para uma distribuição normal. Nesta distribuição é utilizado o desvio padrão igual a 8. Embora esse parâmetro pudesse ser exposto externamente ao algoritmo, decidi não fazer isso. Valores menores favorecem uma exploração mais ampla do espaço de busca, enquanto valores mais altos aumentam a precisão da convergência ao refinar a solução global.
//—————————————————————————————————————————————————————————————————————————————— // Распределение частиц в пространстве поиска void C_AO_AOSm::DistributeParticles () { for (int i = 0; i < popSize; i++) { for (int c = 0; c < coords; c++) { // Используем гауссово распределение для позиционирования частиц a [i].c [c] = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 8); a [i].c [c] = u.SeInDiSp (a [i].c [c], rangeMin [c], rangeMax [c], rangeStep [c]); } } } //——————————————————————————————————————————————————————————————————————————————
Todas as mudanças feitas na versão original do algoritmo AOS foram analisadas com o objetivo de aumentar sua eficiência. Como alterações significativas foram feitas na lógica da estratégia de busca, a versão modificada do algoritmo pode ser indicada pela letra "m". A partir de agora, apenas uma versão modificada será apresentada na tabela de classificação — AOSm.
Exemplo de uso dos algoritmos da classe C_AO
Como todos os algoritmos populacionais de otimização discutidos anteriormente foram herdados da classe comum C_AO, isso permite usá-los de maneira uniforme e com mínimo esforço para resolver diferentes problemas que exigem a busca de parâmetros ótimos. No exemplo abaixo é apresentado um script no qual é realizada a otimização de uma função objetivo:
1. No início do script você pode escolher qual algoritmo de otimização utilizar. Se nada for selecionado, o script informará o erro e será interrompido.
2. Configuração de parâmetros. O script define quantas vezes a função será chamada, quantos parâmetros precisam ser otimizados, o tamanho do grupo de soluções e quantas iterações serão executadas.
3. Limites de valores. Para cada parâmetro são definidos valores mínimos e máximos (neste exemplo de -10 a 10).
4. O script inicia o processo de otimização:
- Ele gera soluções (conjuntos de parâmetros) e verifica o quão boas elas são, utilizando uma função especial (função objetivo).
- A cada iteração, o algoritmo atualiza suas soluções com base naquelas que apresentaram melhores resultados.
5. Resultados. Após a conclusão da otimização, o script exibe informações sobre qual algoritmo foi utilizado, qual o melhor valor encontrado e quantas vezes a função foi executada.
6. A função objetivo — é uma tarefa abstrata de otimização (neste exemplo, a solução de encontrar o máximo global de uma parábola invertida), que recebe os parâmetros e retorna uma avaliação da sua qualidade.
#property script_show_inputs // Указывает, что скрипт будет показывать входные параметры в окне свойств #include <Math\AOs\PopulationAO\#C_AO_enum.mqh> // Подключение библиотеки для работы с алгоритмами оптимизации input E_AO AOexactly = NONE_AO; // Параметр для выбора алгоритма оптимизации, по умолчанию - NONE_AO //—————————————————————————————————————————————————————————————————————————————— void OnStart() { //---------------------------------------------------------------------------- int numbTestFuncRuns = 10000; // Общее количество запусков тестовой функции int params = 1000; // Количество параметров для оптимизации int popSize = 50; // Размер популяции для алгоритма оптимизации int epochCount = numbTestFuncRuns / popSize; // Общее количество эпох (итераций) для оптимизации double rangeMin [], rangeMax [], rangeStep []; // Массивы для хранения границ и шагов параметров ArrayResize (rangeMin, params); // Изменение размера массива min границ ArrayResize (rangeMax, params); // Изменение размера массива max границ ArrayResize (rangeStep, params); // Изменение размера массива шагов // Инициализация границ и шагов для каждого параметра for (int i = 0; i < params; i++) { rangeMin [i] = -10; // Минимальное значение параметра rangeMax [i] = 10; // Максимальное значение параметра rangeStep [i] = DBL_EPSILON; // Шаг для параметра } //---------------------------------------------------------------------------- C_AO *ao = SelectAO (AOexactly); // Выбор алгоритма оптимизации if (ao == NULL) // Проверка, был ли выбран алгоритм { Print ("AO не выбран..."); // Сообщение об ошибке, если алгоритм не выбран return; } ao.params [0].val = popSize; // Назначение размера популяции.... ao.SetParams (); //... (необязательно, тогда будет использован размер популяции по умолчанию) ao.Init (rangeMin, rangeMax, rangeStep, epochCount); // Инициализация алгоритма с заданными границами и количеством эпох // Основной цикл по количеству эпох for (int epochCNT = 1; epochCNT <= epochCount; epochCNT++) { ao.Moving (); // Выполнение одной эпохи алгоритма оптимизации // Вычисление значения целевой функции для каждого решения в популяции for (int set = 0; set < ArraySize (ao.a); set++) { ao.a [set].f = ObjectiveFunction (ao.a [set].c); // Применение целевой функции к каждому решению } ao.Revision (); // Обновление популяции на основе результатов целевой функции } //---------------------------------------------------------------------------- // Вывод имени алгоритма, лучшего результата и количества запусков функции Print (ao.GetName (), ", best result: ", ao.fB, ", number of function launches: ", numbTestFuncRuns); delete ao; // Освобождение памяти, занятой объектом алгоритма } //—————————————————————————————————————————————————————————————————————————————— //—————————————————————————————————————————————————————————————————————————————— // Определение целевой функции пользователя, в данном случае как пример - параболоид, F(Xn) ∈ [0.0; 1.0], X ∈ [-10.0; 10.0], максимизация double ObjectiveFunction (double &x []) { double sum = 0.0; // Переменная для накопления результата // Цикл по всем параметрам for (int i = 0; i < ArraySize (x); i++) { // Проверка, находится ли параметр в допустимом диапазоне if (x [i] < -10.0 || x [i] > 10.0) return 0.0; // Если параметр вне диапазона, возвращаем 0 sum += (-x [i] * x [i] + 100.0) * 0.01; // Вычисление значения целевой функции } return sum /= ArraySize (x); } //——————————————————————————————————————————————————————————————————————————————
Resultados dos testes
Vamos passar para o teste da versão modificada do algoritmo.
AOS|Atomic Orbital Search|50.0|10.0|20.0|0.1|
=============================
5 Hilly's; Func runs: 10000; result: 0.8023218355650774
25 Hilly's; Func runs: 10000; result: 0.7044908398821188
500 Hilly's; Func runs: 10000; result: 0.3102116882841442
=============================
5 Forest's; Func runs: 10000; result: 0.8565993699987462
25 Forest's; Func runs: 10000; result: 0.6945107796904211
500 Forest's; Func runs: 10000; result: 0.21996085558228406
=============================
5 Megacity's; Func runs: 10000; result: 0.7461538461538461
25 Megacity's; Func runs: 10000; result: 0.5286153846153846
500 Megacity's; Func runs: 10000; result: 0.1435846153846167
=============================
All score: 5.00645 (55.63%)
Como pode ser observado, os resultados da versão modificada melhoraram significativamente em comparação com os indicadores anteriores da versão original, onde a pontuação geral foi de 3.00488 (33.39%). Essa melhoria torna-se evidente na análise da visualização, que demonstra não apenas uma melhor convergência, mas também uma exploração mais detalhada dos extremos significativos.
Um dos principais aspectos que merece destaque é o efeito de "agrupamento" das soluções em coordenadas específicas. Esse fenômeno é observado tanto na versão original quanto na modificada, o que ressalta uma característica típica dos algoritmos AOS. O "agrupamento" de soluções pode indicar que o algoritmo está encontrando de forma eficiente as regiões onde se localizam possíveis soluções ótimas.
AOSm na função de teste Hilly
AOSm na função de teste Forest
AOSm na função de teste Megacity
A versão modificada do algoritmo Atomic Orbital Search (AOS) melhorou significativamente seus indicadores em relação à versão original e agora atinge mais de 55% do máximo possível. Este é realmente um resultado impressionante! Na tabela de classificação, o algoritmo ocupa o 12º lugar, na parte superior, o que indica resultados bastante respeitáveis.
№ | AO | Description | Hilly | Hilly final | Forest | Forest final | Megacity (discrete) | Megacity final | Final result | % of MAX | ||||||
10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | 10 p (5 F) | 50 p (25 F) | 1000 p (500 F) | ||||||||
1 | ANS | across neighbourhood search | 0,94948 | 0,84776 | 0,43857 | 2,23581 | 1,00000 | 0,92334 | 0,39988 | 2,32323 | 0,70923 | 0,63477 | 0,23091 | 1,57491 | 6,134 | 68,15 |
2 | CLA | code lock algorithm (joo) | 0,95345 | 0,87107 | 0,37590 | 2,20042 | 0,98942 | 0,91709 | 0,31642 | 2,22294 | 0,79692 | 0,69385 | 0,19303 | 1,68380 | 6,107 | 67,86 |
3 | AMOm | animal migration ptimization M | 0,90358 | 0,84317 | 0,46284 | 2,20959 | 0,99001 | 0,92436 | 0,46598 | 2,38034 | 0,56769 | 0,59132 | 0,23773 | 1,39675 | 5,987 | 66,52 |
4 | (P+O)ES | (P+O) evolution strategies | 0,92256 | 0,88101 | 0,40021 | 2,20379 | 0,97750 | 0,87490 | 0,31945 | 2,17185 | 0,67385 | 0,62985 | 0,18634 | 1,49003 | 5,866 | 65,17 |
5 | CTA | comet tail algorithm (joo) | 0,95346 | 0,86319 | 0,27770 | 2,09435 | 0,99794 | 0,85740 | 0,33949 | 2,19484 | 0,88769 | 0,56431 | 0,10512 | 1,55712 | 5,846 | 64,96 |
6 | SDSm | stochastic diffusion search M | 0,93066 | 0,85445 | 0,39476 | 2,17988 | 0,99983 | 0,89244 | 0,19619 | 2,08846 | 0,72333 | 0,61100 | 0,10670 | 1,44103 | 5,709 | 63,44 |
7 | AAm | archery algorithm M | 0,91744 | 0,70876 | 0,42160 | 2,04780 | 0,92527 | 0,75802 | 0,35328 | 2,03657 | 0,67385 | 0,55200 | 0,23738 | 1,46323 | 5,548 | 61,64 |
8 | ESG | evolution of social groups (joo) | 0,99906 | 0,79654 | 0,35056 | 2,14616 | 1,00000 | 0,82863 | 0,13102 | 1,95965 | 0,82333 | 0,55300 | 0,04725 | 1,42358 | 5,529 | 61,44 |
9 | SIA | simulated isotropic annealing (joo) | 0,95784 | 0,84264 | 0,41465 | 2,21513 | 0,98239 | 0,79586 | 0,20507 | 1,98332 | 0,68667 | 0,49300 | 0,09053 | 1,27020 | 5,469 | 60,76 |
10 | ACS | artificial cooperative search | 0,75547 | 0,74744 | 0,30407 | 1,80698 | 1,00000 | 0,88861 | 0,22413 | 2,11274 | 0,69077 | 0,48185 | 0,13322 | 1,30583 | 5,226 | 58,06 |
11 | ASO | anarchy society optimization | 0,84872 | 0,74646 | 0,31465 | 1,90983 | 0,96148 | 0,79150 | 0,23803 | 1,99101 | 0,57077 | 0,54062 | 0,16614 | 1,27752 | 5,178 | 57,54 |
12 | AOSm | atomic orbital search M | 0,80232 | 0,70449 | 0,31021 | 1,81702 | 0,85660 | 0,69451 | 0,21996 | 1,77107 | 0,74615 | 0,52862 | 0,14358 | 1,41835 | 5,006 | 55,63 |
13 | TSEA | turtle shell evolution algorithm (joo) | 0,96798 | 0,64480 | 0,29672 | 1,90949 | 0,99449 | 0,61981 | 0,22708 | 1,84139 | 0,69077 | 0,42646 | 0,13598 | 1,25322 | 5,004 | 55,60 |
14 | DE | differential evolution | 0,95044 | 0,61674 | 0,30308 | 1,87026 | 0,95317 | 0,78896 | 0,16652 | 1,90865 | 0,78667 | 0,36033 | 0,02953 | 1,17653 | 4,955 | 55,06 |
15 | CRO | chemical reaction optimisation | 0,94629 | 0,66112 | 0,29853 | 1,90593 | 0,87906 | 0,58422 | 0,21146 | 1,67473 | 0,75846 | 0,42646 | 0,12686 | 1,31178 | 4,892 | 54,36 |
16 | BSA | bird swarm algorithm | 0,89306 | 0,64900 | 0,26250 | 1,80455 | 0,92420 | 0,71121 | 0,24939 | 1,88479 | 0,69385 | 0,32615 | 0,10012 | 1,12012 | 4,809 | 53,44 |
17 | HS | harmony search | 0,86509 | 0,68782 | 0,32527 | 1,87818 | 0,99999 | 0,68002 | 0,09590 | 1,77592 | 0,62000 | 0,42267 | 0,05458 | 1,09725 | 4,751 | 52,79 |
18 | SSG | saplings sowing and growing | 0,77839 | 0,64925 | 0,39543 | 1,82308 | 0,85973 | 0,62467 | 0,17429 | 1,65869 | 0,64667 | 0,44133 | 0,10598 | 1,19398 | 4,676 | 51,95 |
19 | BCOm | bacterial chemotaxis optimization M | 0,75953 | 0,62268 | 0,31483 | 1,69704 | 0,89378 | 0,61339 | 0,22542 | 1,73259 | 0,65385 | 0,42092 | 0,14435 | 1,21912 | 4,649 | 51,65 |
20 | ABO | african buffalo optimization | 0,83337 | 0,62247 | 0,29964 | 1,75548 | 0,92170 | 0,58618 | 0,19723 | 1,70511 | 0,61000 | 0,43154 | 0,13225 | 1,17378 | 4,634 | 51,49 |
21 | (PO)ES | (PO) evolution strategies | 0,79025 | 0,62647 | 0,42935 | 1,84606 | 0,87616 | 0,60943 | 0,19591 | 1,68151 | 0,59000 | 0,37933 | 0,11322 | 1,08255 | 4,610 | 51,22 |
22 | TSm | tabu search M | 0,87795 | 0,61431 | 0,29104 | 1,78330 | 0,92885 | 0,51844 | 0,19054 | 1,63783 | 0,61077 | 0,38215 | 0,12157 | 1,11449 | 4,536 | 50,40 |
23 | BSO | brain storm optimization | 0,93736 | 0,57616 | 0,29688 | 1,81041 | 0,93131 | 0,55866 | 0,23537 | 1,72534 | 0,55231 | 0,29077 | 0,11914 | 0,96222 | 4,498 | 49,98 |
24 | WOAm | wale optimization algorithm M | 0,84521 | 0,56298 | 0,26263 | 1,67081 | 0,93100 | 0,52278 | 0,16365 | 1,61743 | 0,66308 | 0,41138 | 0,11357 | 1,18803 | 4,476 | 49,74 |
25 | AEFA | artificial electric field algorithm | 0,87700 | 0,61753 | 0,25235 | 1,74688 | 0,92729 | 0,72698 | 0,18064 | 1,83490 | 0,66615 | 0,11631 | 0,09508 | 0,87754 | 4,459 | 49,55 |
26 | AEO | artificial ecosystem-based optimization algorithm | 0,91380 | 0,46713 | 0,26470 | 1,64563 | 0,90223 | 0,43705 | 0,21400 | 1,55327 | 0,66154 | 0,30800 | 0,28563 | 1,25517 | 4,454 | 49,49 |
27 | ACOm | ant colony optimization M | 0,88190 | 0,66127 | 0,30377 | 1,84693 | 0,85873 | 0,58680 | 0,15051 | 1,59604 | 0,59667 | 0,37333 | 0,02472 | 0,99472 | 4,438 | 49,31 |
28 | BFO-GA | bacterial foraging optimization - ga | 0,89150 | 0,55111 | 0,31529 | 1,75790 | 0,96982 | 0,39612 | 0,06305 | 1,42899 | 0,72667 | 0,27500 | 0,03525 | 1,03692 | 4,224 | 46,93 |
29 | ABHA | artificial bee hive algorithm | 0,84131 | 0,54227 | 0,26304 | 1,64663 | 0,87858 | 0,47779 | 0,17181 | 1,52818 | 0,50923 | 0,33877 | 0,10397 | 0,95197 | 4,127 | 45,85 |
30 | ACMO | atmospheric cloud model optimization | 0,90321 | 0,48546 | 0,30403 | 1,69270 | 0,80268 | 0,37857 | 0,19178 | 1,37303 | 0,62308 | 0,24400 | 0,10795 | 0,97503 | 4,041 | 44,90 |
31 | ASHA | artificial showering algorithm | 0,89686 | 0,40433 | 0,25617 | 1,55737 | 0,80360 | 0,35526 | 0,19160 | 1,35046 | 0,47692 | 0,18123 | 0,09774 | 0,75589 | 3,664 | 40,71 |
32 | ASBO | adaptive social behavior optimization | 0,76331 | 0,49253 | 0,32619 | 1,58202 | 0,79546 | 0,40035 | 0,26097 | 1,45677 | 0,26462 | 0,17169 | 0,18200 | 0,61831 | 3,657 | 40,63 |
33 | MEC | mind evolutionary computation | 0,69533 | 0,53376 | 0,32661 | 1,55569 | 0,72464 | 0,33036 | 0,07198 | 1,12698 | 0,52500 | 0,22000 | 0,04198 | 0,78698 | 3,470 | 38,55 |
34 | IWO | invasive weed optimization | 0,72679 | 0,52256 | 0,33123 | 1,58058 | 0,70756 | 0,33955 | 0,07484 | 1,12196 | 0,42333 | 0,23067 | 0,04617 | 0,70017 | 3,403 | 37,81 |
35 | Micro-AIS | micro artificial immune system | 0,79547 | 0,51922 | 0,30861 | 1,62330 | 0,72956 | 0,36879 | 0,09398 | 1,19233 | 0,37667 | 0,15867 | 0,02802 | 0,56335 | 3,379 | 37,54 |
36 | COAm | cuckoo optimization algorithm M | 0,75820 | 0,48652 | 0,31369 | 1,55841 | 0,74054 | 0,28051 | 0,05599 | 1,07704 | 0,50500 | 0,17467 | 0,03380 | 0,71347 | 3,349 | 37,21 |
37 | SDOm | spiral dynamics optimization M | 0,74601 | 0,44623 | 0,29687 | 1,48912 | 0,70204 | 0,34678 | 0,10944 | 1,15826 | 0,42833 | 0,16767 | 0,03663 | 0,63263 | 3,280 | 36,44 |
38 | NMm | Nelder-Mead method M | 0,73807 | 0,50598 | 0,31342 | 1,55747 | 0,63674 | 0,28302 | 0,08221 | 1,00197 | 0,44667 | 0,18667 | 0,04028 | 0,67362 | 3,233 | 35,92 |
39 | FAm | firefly algorithm M | 0,58634 | 0,47228 | 0,32276 | 1,38138 | 0,68467 | 0,37439 | 0,10908 | 1,16814 | 0,28667 | 0,16467 | 0,04722 | 0,49855 | 3,048 | 33,87 |
40 | GSA | gravitational search algorithm | 0,64757 | 0,49197 | 0,30062 | 1,44016 | 0,53962 | 0,36353 | 0,09945 | 1,00260 | 0,32667 | 0,12200 | 0,01917 | 0,46783 | 2,911 | 32,34 |
41 | BFO | bacterial foraging optimization | 0,61171 | 0,43270 | 0,31318 | 1,35759 | 0,54410 | 0,21511 | 0,05676 | 0,81597 | 0,42167 | 0,13800 | 0,03195 | 0,59162 | 2,765 | 30,72 |
42 | ABC | artificial bee colony | 0,63377 | 0,42402 | 0,30892 | 1,36671 | 0,55103 | 0,21874 | 0,05623 | 0,82600 | 0,34000 | 0,14200 | 0,03102 | 0,51302 | 2,706 | 30,06 |
43 | BA | bat algorithm | 0,59761 | 0,45911 | 0,35242 | 1,40915 | 0,40321 | 0,19313 | 0,07175 | 0,66810 | 0,21000 | 0,10100 | 0,03517 | 0,34617 | 2,423 | 26,93 |
44 | AAA | algae adaptive algorithm | 0,50007 | 0,32040 | 0,25525 | 1,07572 | 0,37021 | 0,22284 | 0,16785 | 0,76089 | 0,27846 | 0,14800 | 0,09755 | 0,52402 | 2,361 | 26,23 |
45 | SA | simulated annealing | 0,55787 | 0,42177 | 0,31549 | 1,29513 | 0,34998 | 0,15259 | 0,05023 | 0,55280 | 0,31167 | 0,10033 | 0,02883 | 0,44083 | 2,289 | 25,43 |
Considerações finais
Neste artigo foi apresentada a versão modificada do algoritmo de busca orbital atômica (AOSm), na qual abandonei a posição média dos elétrons BSk nas camadas do átomo em favor da melhor posição individual de cada elétron. Isso permitiu que os elétrons se movessem de forma mais eficiente em direção à melhor solução em sua camada, baseando-se em suas próprias conquistas e não em uma média geral. Além disso, foram eliminados dois componentes aleatórios βi e γi, o que reduziu em três vezes o tempo de geração de números aleatórios, sem perder o sentido físico do algoritmo.
No método "UpdateElectrons", foram removidas as variáveis que se tornaram desnecessárias e foi eliminada a divisão do incremento do elétron pelo número de camadas durante o movimento em direção à solução global. Embora os autores da versão original possivelmente tenham buscado tornar a intensidade de movimento variável, meus experimentos mostraram que isso não trouxe benefícios significativos.
Também foram implementadas mudanças no método "UpdateElectrons" da classe "C_AO_AOSm", substituindo a dispersão aleatória do elétron pelo movimento em direção ao centro do núcleo com uma determinada probabilidade. Isso melhorou as propriedades combinatórias do algoritmo, permitindo que os elétrons focassem com mais precisão no objetivo global. Além disso, a distribuição lognormal foi substituída pela distribuição normal, o que aumentou a precisão da convergência na busca pelo refinamento da solução global.
Os resultados da versão modificada AOSm mostraram uma melhoria significativa, com uma pontuação geral superior a 55% do máximo possível, o que confirma a alta eficiência e competitividade do algoritmo. Na tabela de classificação, o AOSm ocupa a 12ª posição, o que evidencia suas conquistas significativas entre outros métodos de otimização.
Um dos aspectos mais notáveis do AOSm é a melhoria na convergência, que se tornou evidente na visualização dos resultados. O algoritmo trabalha de forma mais detalhada os extremos significativos e demonstra capacidade de busca eficiente por soluções ótimas em espaços complexos e multidimensionais. O efeito de "agrupamento" de soluções, observado tanto na versão original quanto na modificada, destaca a habilidade do algoritmo em encontrar e se concentrar em regiões com potenciais ótimos, o que é especialmente útil em problemas de alta dimensionalidade e estrutura complexa.
Um benefício adicional da versão modificada é a redução do número de parâmetros externos, o que simplifica seu uso e configuração. Contudo, para todos os algoritmos apresentados anteriormente nos artigos, selecionei parâmetros externos otimizados para alcançar o máximo desempenho em testes complexos com diferentes tipos de problemas, portanto, todos os algoritmos estão prontos para uso e não requerem ajustes. Nesta série de artigos ficou demonstrado que, às vezes, pequenas alterações nos algoritmos de otimização podem mudar radicalmente suas propriedades de busca, enquanto grandes mudanças na lógica da estratégia de busca podem não resultar em melhorias perceptíveis. E, claro, compartilho nos artigos técnicas que realmente aumentam a eficiência da otimização.
Figura 2. Graduação de cores dos algoritmos conforme os respectivos testes. Os resultados maiores ou iguais a 0.99 são destacados em branco.
Figura 3. Histograma dos resultados dos testes dos algoritmos (na escala de 0 a 100, quanto maior, melhor,
onde 100 é o resultado teórico máximo possível, no arquivo compactado há o script para o cálculo da tabela de classificação)
Prós e contras do algoritmo AOSm:
Prós:
- Boa performance em diferentes tipos de problemas.
- Pequeno número de parâmetros externos.
- Boa escalabilidade.
- Busca equilibrada tanto em extremos locais quanto globais.
Contras:
- Implementação relativamente complexa.
- Precisão de convergência média em comparação com outros algoritmos em funções suaves.
Está anexado ao artigo um arquivo compactado com as versões atualizadas dos códigos dos algoritmos. O autor do artigo não se responsabiliza pela precisão absoluta na descrição dos algoritmos canônicos, pois muitas alterações foram feitas para melhorar suas capacidades de busca. As conclusões e julgamentos apresentados nos artigos baseiam-se nos resultados dos experimentos realizados.
Programas utilizados no artigo
# | Nome | Tipo | Descrição |
---|---|---|---|
1 | #C_AO.mqh | Arquivo incluído | Classe pai dos algoritmos populacionais de otimização |
2 | #C_AO_enum.mqh | Arquivo incluído | Enumeração dos algoritmos populacionais de otimização |
3 | TestFunctions.mqh | Arquivo incluído | Biblioteca de funções de teste |
4 | TestStandFunctions.mqh | Arquivo incluído | Biblioteca de funções da bancada de testes |
5 | Utilities.mqh | Arquivo incluído | Biblioteca de funções auxiliares |
6 | CalculationTestResults.mqh | Arquivo incluído | Script para cálculo dos resultados na tabela comparativa |
7 | Testing AOs.mq5 | Script | Bancada de testes unificada para todos os algoritmos populacionais de otimização |
8 | Simple use of population optimization algorithms.mq5 | Script | Exemplo simples de uso dos algoritmos populacionais de otimização sem visualização |
9 | AO_AOSm_AtomicOrbitalSearch.mqh | Arquivo incluído | Classe do algoritmo AOSm |
10 | Test_AO_AOSm.mq5 | Script | Bancada de testes para o AOSm |
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/16315





- 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