Русский Español
preview
Algoritmo do Restaurateur de Sucesso — Successful Restaurateur Algorithm (SRA)

Algoritmo do Restaurateur de Sucesso — Successful Restaurateur Algorithm (SRA)

MetaTrader 5Testador |
124 0
Andrey Dik
Andrey Dik

Conteúdo

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


Introdução

Sempre me fascinaram os paralelos entre problemas de otimização e cenários da vida real. Ao explorar novos caminhos para algoritmos meta-heurísticos, percebi semelhanças entre a otimização populacional e a evolução de um restaurante. Essa ideia se tornou a inspiração para o que chamo de "Algoritmo do Restaurateur de Sucesso" (SRA).

Imagine o dono de um restaurante que busca constantemente melhorar seu cardápio para aumentar sua popularidade e atrair novos clientes. Em vez de simplesmente eliminar os pratos menos pedidos, ele segue uma estratégia mais refinada: identifica o item menos popular e o combina cuidadosamente com elementos dos pratos mais apreciados. Às vezes, as mudanças são conservadoras; em outras ocasiões, incluem novos ingredientes ousados. O objetivo, porém, é sempre o mesmo: transformar a opção menos pedida em algo capaz de se tornar o novo favorito do cardápio.

Essa metáfora culinária define a base do SRA. Ao contrário dos algoritmos evolucionários tradicionais, que geralmente descartam soluções malsucedidas, o SRA foca na recuperação dos piores desempenhos, incorporando a eles elementos de sucesso. Essa estratégia mantém a diversidade no espaço de soluções enquanto eleva gradualmente a qualidade geral da população.

Neste artigo, analisaremos os principais mecanismos do SRA, sua implementação e como parâmetros, como "temperatura" e "intensidade dos experimentos culinários", regulam o equilíbrio entre intensificação e diversificação. Apresentarei também os resultados dos testes que comparam o SRA com outros algoritmos reconhecidos em um ranking de diferentes funções de teste.

O que começou como um experimento mental criativo se transformou em uma abordagem promissora com características únicas. Convido você a descobrir como esse algoritmo, inspirado no ramo da restauração, oferece soluções de otimização com um sabor especial.


Implementação do algoritmo

Vamos destrinchar o funcionamento do algoritmo por meio de analogias simples. Imagine que eu sou o dono de um restaurante. Tenho um cardápio com vários pratos e percebo que alguns são muito populares, enquanto outros quase não são pedidos pelos clientes. O que eu faço? Eu não retiro imediatamente os pratos impopulares do cardápio (o que reduziria a variedade disponível), mas pego o menos popular e tento melhorá-lo. Como? Eu observo os itens de maior sucesso do restaurante e extraio deles algumas ideias ou ingredientes. Por exemplo, suponha que um prato de peixe esteja com vendas fracas, mas a salada seja extremamente popular. Então, incorporo ao prato de peixe algum elemento dessa salada de sucesso (talvez um molho especial ou uma forma de apresentação) e crio algo novo.

Às vezes, faço pequenas mudanças; outras vezes, arrisco experimentos ousados. No início, quando acabei de abrir o restaurante, eu fazia muitas experiências, mas, depois de encontrar alguns pratos de grande sucesso, passei a refinar mais cuidadosamente as combinações de ingredientes e suas proporções. Com o tempo, até mesmo os pratos mais fracos do cardápio ficam cada vez melhores. E, em certos casos, aquele antigo "azarão" pode se transformar em um novo sucesso! Dessa forma, a popularidade geral do restaurante aumenta, pois todos os itens acabam tendo boa aceitação.

É exatamente assim que meu algoritmo funciona: não descartamos as más soluções, mas as melhoramos continuamente com ideias das melhores soluções. E, quanto mais o processo avança, menos experimentamos de forma radical e mais refinamos o que já foi descoberto. A figura 1 mostra o diagrama de funcionamento do algoritmo.

sra-algorithm-flow

Figura 1. Diagrama de funcionamento do algoritmo SRA

O diagrama tem início no bloco "Inicialização", onde o cardápio inicial é criado. Em seguida, ocorre o ciclo principal do algoritmo, cujo centro é o cardápio atual do restaurante, ordenado pela qualidade dos pratos. Esse cardápio é representado por um gradiente de cores, que vai do verde (melhores pratos) ao vermelho (piores pratos). Abaixo, estão quatro etapas sequenciais: a primeira é a escolha dos pratos a serem melhorados, na qual o pior prato e um doador de alta qualidade são selecionados, e essa seleção é influenciada por uma probabilidade crescente de acordo com a lei quadrática; a segunda é a criação de novas versões por meio da combinação de receitas e da mutação de ingredientes (quanto maior a temperatura, mais ousados os experimentos); a terceira é a avaliação dos novos pratos pelo cálculo da função de adaptabilidade; e a quarta é a redução da temperatura para diminuir a intensidade dos experimentos. À esquerda, uma seta tracejada indica que o processo se repete até atingir a convergência ou satisfazer o critério de parada. À direita, as marcações: A (círculo verde) — melhores pratos, B (círculo vermelho) — piores pratos. Todo o esquema ilustra o processo que remete ao trabalho do restaurateur, que melhora sistematicamente os pontos fracos do cardápio aproveitando elementos dos pratos de maior sucesso.

Agora vamos passar à escrita do pseudocódigo do algoritmo SRA.

//Inicialização
Criar uma população de popSize agentes (pratos do cardápio)
Para cada agente:
    Inicializar aleatoriamente todas as coordenadas dentro dos limites permitidos
Definir a temperatura inicial = 1.0
Definir o coeficiente de resfriamento = 0.98
Definir a intensidade dos experimentos culinários = 0.3

//Ciclo principal do algoritmo
ENQUANTO não for satisfeito o critério de parada:
    //Etapa 1: Avaliação de todos os agentes
    Para cada agente:
        Calcular o valor da função de adaptabilidade
    
    // Combinar a população atual e a anterior
    Formar o cardápio geral com os agentes atuais e os anteriores
    Ordenar o cardápio geral pelo valor da função de adaptabilidade do melhor para o pior
    
    //Etapa 2: Criação de novas variantes
    Para cada agente na nova população:
        // Pegamos o pior elemento da primeira metade da população ordenada
        Copiar as coordenadas do agente com índice (popSize-1)
        
        // Escolha entre melhoria e experimento
        Se (número_aleatório < (1.0 - menuInnovationRate * temperatura)):
            // Escolha do "doador" pelo método da roleta quadrática
            r = número aleatório entre 0 e 1
            r = r²
            donorIndex = escalar r entre 0 e (popSize-1)
            
            // Para cada coordenada
            Para cada coordenada c:
                // Com probabilidade de 0.8, copiar coordenada do doador
                Se (número_aleatório < 0.8):
                    agente_atual.c = doador.c
                
                // Mutação adaptativa
                mutationRate = 0.1 + 0.4 * temperatura * (índice_agente / popSize)
                Se (número_aleatório < mutationRate):
                    // Escolha do tipo de mutação
                    Se (número_aleatório < 0.5):
                        agente_atual.c = distribuição gaussiana(agente_atual.c)
                    Caso contrário:
                        agente_atual.c = valor aleatório no intervalo
                    
                    // Garantir que o valor esteja dentro dos limites permitidos
                    agente_atual.c = arredondar para o valor válido mais próximo
        Caso contrário:
            // Criação de um novo "prato"
            Para cada coordenada c:
                Se (número_aleatório < 0.7):
                    agente_atual.c = valor aleatório no intervalo
                Caso contrário:
                    agente_atual.c = distribuição gaussiana(melhor_solucao.c)
                
                // Garantir que o valor esteja dentro dos limites permitidos
                agente_atual.c = arredondar para o valor válido mais próximo
        
        // Elitismo — às vezes é útil simplesmente adicionar elementos da melhor solução
        Se (número_aleatório < 0.1):
            numEliteCoords = número aleatório entre 1 e (coords * 0.3)
            Para i de 1 até numEliteCoords:
                c = índice aleatório da coordenada
                agente_atual.c = melhor_solucao.c
    
    // Etapa 3: Atualização da melhor solução
    Para cada agente:
        Se agente.fitness > melhor_solucao.fitness:
            melhor_solucao = agente
    
    // Etapa 4: Redução da temperatura
    temperatura = temperatura * taxa_de_resfriamento
    Se temperatura < 0.1:
        temperatura = 0.1

Retornar melhor_solucao

Agora podemos começar a escrever o código do algoritmo. Vamos implementar a classe "C_AO_SRA", que herda da classe principal "C_AO" e realiza a lógica do SRA. Vamos detalhar como ela funciona.

Construtor e destrutor: popSize, temperature, coolingRate, menuInnovationRate definem as principais características do algoritmo, como o número de agentes e os parâmetros de controle do processo de busca.

Método SetParams: atualiza os parâmetros da classe com base nos valores armazenados no array "params", parâmetros estes que foram previamente inicializados no construtor.

Método Init: responsável pela inicialização do algoritmo. Ele recebe os valores mínimos e máximos, o passo de variação dos parâmetros e o número de épocas, preparando o algoritmo para executar a tarefa de busca.

Métodos Moving e Revision: implementam as etapas principais do algoritmo, ligadas ao movimento (ou atualização) do estado dos agentes e ao "Revision", que trata da revisão e adaptação dos parâmetros.

Membros da classe:

  • temperature — a temperatura atual, ligada ao controle da diversificação e ao cronograma de resfriamento do algoritmo.
  • coolingRate — a taxa de resfriamento, usada para definir a velocidade de redução da temperatura.
  • menuInnovationRate — a intensidade dos experimentos culinários, que indica até que ponto os agentes são estimulados a buscar novas soluções.
Membros privados da classe:
  • S_AO_Agent menu [] — array de agentes, representando o "cardápio" no contexto do algoritmo SRA.
  • S_AO_Agent menuT [] — array de agentes usado para armazenamento temporário de variações dos pratos.
//——————————————————————————————————————————————————————————————————————————————
class C_AO_SRA : public C_AO
{
  public: //--------------------------------------------------------------------
  ~C_AO_SRA () { }
  C_AO_SRA ()
  {
    ao_name = "SRA";
    ao_desc = "Successful Restaurateur Algorithm (joo)";
    ao_link = "https://www.mql5.com/ru/articles/17380";

    popSize            = 50;   // число агентов (размер "меню")
    temperature        = 1.0;  // начальная "температура" для управления исследованием
    coolingRate        = 0.98; // скорость охлаждения
    menuInnovationRate = 0.3;  // интенсивность кулинарных экспериментов

    ArrayResize (params, 4);

    params [0].name = "popSize";            params [0].val = popSize;
    params [1].name = "temperature";        params [1].val = temperature;
    params [2].name = "coolingRate";        params [2].val = coolingRate;
    params [3].name = "menuInnovationRate"; params [3].val = menuInnovationRate;
  }

  void SetParams ()
  {
    popSize            = (int)params [0].val;
    temperature        = params      [1].val;
    coolingRate        = params      [2].val;
    menuInnovationRate = params      [3].val;
  }

  bool Init (const double &rangeMinP  [],  // минимальные значения
             const double &rangeMaxP  [],  // максимальные значения
             const double &rangeStepP [],  // шаг изменения
             const int     epochsP = 0);   // количество эпох

  void Moving   ();
  void Revision ();

  //----------------------------------------------------------------------------
  double temperature;        // текущая "температура"
  double coolingRate;        // скорость охлаждения
  double menuInnovationRate; // интенсивность кулинарных экспериментов

  private: //-------------------------------------------------------------------
  S_AO_Agent menu  [];
  S_AO_Agent menuT [];
};
//——————————————————————————————————————————————————————————————————————————————

O método "Init" da classe "C_AO_SRA" realiza a inicialização do algoritmo:

Verificação da inicialização padrão: o método chama "StandardInit" com os valores mínimos e máximos dos intervalos e os passos. Caso falhe, retorna "false".

Inicialização dos arrays:

  • Distribui os tamanhos dos arrays "menu" e "menuT" de acordo com a quantidade de agentes.
  • Inicializa cada agente no array "menu".

Reinício da temperatura: define o valor inicial de "temperature" como "1.0".

Conclusão bem-sucedida: retorna "true" caso a inicialização seja realizada corretamente.

//——————————————————————————————————————————————————————————————————————————————
//--- Инициализация
bool C_AO_SRA::Init (const double &rangeMinP  [],
                     const double &rangeMaxP  [],
                     const double &rangeStepP [],
                     const int epochsP = 0)
{
  if (!StandardInit (rangeMinP, rangeMaxP, rangeStepP)) return false;

  //----------------------------------------------------------------------------
  ArrayResize (menu,  popSize * 2);
  ArrayResize (menuT, popSize * 2);

  for (int p = 0; p < popSize * 2; p++) menu [p].Init (coords);

  temperature = 1.0; // сброс температуры при инициализации

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

O método "Moving" da classe "C_AO_SRA" implementa a etapa principal do algoritmo. Ele possui duas partes principais: a inicialização dos agentes e sua adaptação através de mutação e criação de novas soluções.

Inicialização inicial (quando "revision" é igual a "false"):
  • Cada agente é inicializado com valores aleatórios dentro dos limites definidos (rangeMin, rangeMax), aplicando os passos (rangeStep). Os valores são armazenados em "c" e "cB" para cada agente.
  • Define "revision" como "true" e encerra o método.

Redução da temperatura: a temperatura é multiplicada pelo coeficiente de resfriamento (coolingRate), o que influencia as probabilidades de mudanças subsequentes.

Ciclo principal dos agentes: para cada agente, seleciona-se o pior elemento da primeira metade da população ordenada (a partir do array menu).

Classificação das ações: com uma probabilidade dependente da temperatura, o agente pode:

  • modificar a solução atual (usando uma "receita-doador" de um prato de melhor qualidade), aplicando mutação com probabilidade variável.
  • criar uma nova solução (valores aleatórios).

Elitismo: com determinada probabilidade, ao novo resultado podem ser adicionados elementos da melhor solução encontrada.

//——————————————————————————————————————————————————————————————————————————————
//--- Основной шаг алгоритма
void C_AO_SRA::Moving ()
{
  //----------------------------------------------------------------------------
  // Начальная инициализация
  if (!revision)
  {
    for (int p = 0; p < popSize; p++)
    {
      for (int c = 0; c < coords; c++)
      {
        a [p].c  [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
        a [p].c  [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
        a [p].cB [c] = a [p].c [c];
      }
    }

    revision = true;
    return;
  }

  //----------------------------------------------------------------------------
  // Снижаем температуру
  temperature *= coolingRate;

  // Основной цикл по агентам популяции
  for (int p = 0; p < popSize; p++)
  {
    // Берем худший элемент из первой половины отсортированной популяции (с индексом popSize-1)
    // Помним, что в menu элементы отсортированы от лучшего к худшему
    ArrayCopy (a [p].c, menu [popSize - 1].c, 0, 0, WHOLE_ARRAY);

    // Решаем, создавать ли гибрид или экспериментировать с новым "блюдом"
    // Вероятность эксперимента зависит от температуры - в начале больше экспериментов
    if (u.RNDprobab () < (1.0 - menuInnovationRate * temperature))
    {
      // Выбираем "рецепт-донор" с вероятностью пропорциональной успешности блюда
      double r = u.RNDprobab ();
      r = pow (r, 2);                                         // Усиление предпочтения к лучшим блюдам
      int menuIND = (int)u.Scale (r, 0, 1.0, 0, popSize - 1); // Лучшие в начале массива

      // Для каждой координаты
      for (int c = 0; c < coords; c++)
      {
        // С вероятностью, зависящей от температуры, берем параметр из успешного блюда
        if (u.RNDprobab () < 0.8)
        {
          a [p].c [c] = menu [menuIND].c [c];
        }

        // Мутация с адаптивной вероятностью - чем дальше от лучшего решения и выше температура, тем больше мутаций
        double mutationRate = 0.1 + 0.4 * temperature * (double)(p) / popSize;
        if (u.RNDprobab () < mutationRate)
        {
          // Комбинация различных типов мутаций
          if (u.RNDprobab () < 0.5) a [p].c [c] = u.GaussDistribution (a [p].c [c], rangeMin [c], rangeMax [c], 2);
          else                      a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]); // Иногда полностью новое значение

          // Убедимся, что значение в допустимых пределах
          a [p].c [c] = u.SeInDiSp (a [p].c [c], rangeMin [c], rangeMax [c], rangeStep [c]);
        }
      }
    }
    else // Создаем абсолютно новое "блюдо"
    {
      for (int c = 0; c < coords; c++)
      {
        // Вариация 1: полностью случайное значение
        if (u.RNDprobab () < 0.7)
        {
          a [p].c [c] = u.RNDfromCI (rangeMin [c], rangeMax [c]);
        }
        // Вариация 2: основано на лучшем найденном решении с большим отклонением
        else
        {
          a [p].c [c] = u.GaussDistribution (cB [c], rangeMin [c], rangeMax [c], 1);
        }

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

    // Иногда добавляем элементы из лучшего решения напрямую (элитизм)
    if (u.RNDprobab () < 0.1)
    {
      int numEliteCoords = u.RNDintInRange (1, coords / 3); // Берем от 1 до 30% координат
      for (int i = 0; i < numEliteCoords; i++)
      {
        int c = u.RNDminusOne (coords);
        a [p].c [c] = cB [c]; // Берем значение из лучшего решения
      }
    }
  }
}
//——————————————————————————————————————————————————————————————————————————————

O método "Revision" da classe "C_AO_SRA" é responsável por atualizar a melhor solução encontrada e por gerenciar o "cardápio" geral de soluções durante a execução do algoritmo:

Busca do melhor agente: percorre todos os agentes da população atual e identifica aquele com o maior valor da função de adaptabilidade (f). Se for encontrado um novo melhor agente, atualiza "fB" e o índice "bestIND".

Atualização da melhor solução: se for identificado um melhor agente (isto é, se bestIND for diferente de -1), copia seus parâmetros de solução (c) para a variável cB, que representa a solução atual de maior qualidade.

Atualização do cardápio geral: adiciona os parâmetros atuais de todos os agentes ao "cardápio", permitindo armazenar os experimentos realizados.

Ordenação do cardápio: organiza o array "menu" pela função de adaptabilidade, do melhor para o pior, garantindo que as melhores soluções permaneçam na primeira metade. Isso será utilizado na próxima iteração do algoritmo.

Controle de temperatura: estabelece um limite inferior para a temperatura, assegurando que ela não caia abaixo de "0.1", evitando assim uma convergência prematura.
//——————————————————————————————————————————————————————————————————————————————
//--- Обновление лучшего решения с учетом жадного выбора и вероятности принятия худших решений
void C_AO_SRA::Revision ()
{
  int bestIND = -1;

  // Находим лучшего агента в текущей популяции
  for (int p = 0; p < popSize; p++)
  {
    if (a [p].f > fB)
    {
      fB = a [p].f;
      bestIND = p;
    }
  }

  // Если нашли лучшее решение, обновляем cB
  if (bestIND != -1) ArrayCopy (cB, a [bestIND].c, 0, 0, WHOLE_ARRAY);

  // Добавляем текущий набор блюд в общее "меню"
  for (int p = 0; p < popSize; p++)
  {
    menu [popSize + p] = a [p];
  }

  // Сортируем всё "меню" от лучших к худшим решениям
  // После сортировки, первая половина menu будет содержать лучшие решения,
  // которые будут использоваться на следующей итерации
  u.Sorting (menu, menuT, popSize * 2);

  // Не позволяем температуре упасть ниже определенного порога
  if (temperature < 0.1) temperature = 0.1;
}
//——————————————————————————————————————————————————————————————————————————————


Resultados dos testes

Agora podemos observar como o algoritmo SRA funciona. Abaixo está a saída dos resultados de teste:

SRA|Successful Restaurateur Algorithm|50.0|1.0|0.98|0.3|
=============================
5 Hilly's; Func runs: 10000; result: 0.9688326305968623
25 Hilly's; Func runs: 10000; result: 0.6345483084017249
500 Hilly's; Func runs: 10000; result: 0.292167027537253
=============================
5 Forest's; Func runs: 10000; result: 0.946368863880973
25 Forest's; Func runs: 10000; result: 0.5550607959254661
500 Forest's; Func runs: 10000; result: 0.19124225531141872
=============================
5 Megacity's; Func runs: 10000; result: 0.7492307692307693
25 Megacity's; Func runs: 10000; result: 0.4403076923076923
500 Megacity's; Func runs: 10000; result: 0.12526153846153956
=============================
All score: 4.90302 (54.48%)

A visualização do funcionamento do algoritmo SRA no ambiente de teste permite tirar conclusões sobre as características de sua estratégia de busca. Nesse caso, observa-se uma ampla diversificação do espaço de busca, com os agentes distribuídos de maneira relativamente uniforme e explorando até mesmo as regiões mais distantes. Ao mesmo tempo, não há sinais significativos de agrupamento em extremos locais e os movimentos dos agentes parecem caóticos.

Entretanto, apesar da boa capacidade de diversificação, o algoritmo apresenta certas limitações no refinamento das soluções, o que se reflete em uma precisão relativamente baixa de convergência. Também vale destacar uma pequena variação nos resultados obtidos durante os testes.

Hilly

SRA na função de teste Hilly

Forest

SRA na função de teste Forest

Megacity

SRA na função de teste Megacity

Com base nos testes realizados, o algoritmo ocupa a 20ª posição no ranking dos algoritmos populacionais de otimização mais fortes. Atualmente, a tabela inclui nove algoritmos autorais de otimização (joo), entre os quais está o novo algoritmo SRA.

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 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
7 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
8 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
9 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
10 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
11 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
12 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
13 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
14 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
15 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
16 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
17 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
18 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
19 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
20 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
21 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
22 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
23 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
24 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
25 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
26 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
27 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
28 (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
29 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
30 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
31 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
32 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
33 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
34 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
35 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
36 SOA simple optimization algorithm 0,91520 0,46976 0,27089 1,65585 0,89675 0,37401 0,16984 1,44060 0,69538 0,28031 0,10852 1,08422 4,181 46,45
37 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
38 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
39 ADAMm adaptive moment estimation M 0,88635 0,44766 0,26613 1,60014 0,84497 0,38493 0,16889 1,39880 0,66154 0,27046 0,10594 1,03794 4,037 44,85
40 CGO chaos game optimization 0,57256 0,37158 0,32018 1,26432 0,61176 0,61931 0,62161 1,85267 0,37538 0,21923 0,19028 0,78490 3,902 43,35
41 ATAm artificial tribe algorithm M 0,71771 0,55304 0,25235 1,52310 0,82491 0,55904 0,20473 1,58867 0,44000 0,18615 0,09411 0,72026 3,832 42,58
42 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
43 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
44 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
45 CSA circle search algorithm 0,66560 0,45317 0,29126 1,41003 0,68797 0,41397 0,20525 1,30719 0,37538 0,23631 0,10646 0,71815 3,435 38,17
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


Considerações finais

Após desenvolver e testar o Algoritmo do Restaurateur de Sucesso (SRA), afirmo com segurança que ele apresentou um desempenho respeitável. No momento, ele ocupa a 20ª posição no ranking, o que, para uma nova abordagem, é um resultado bastante positivo. Analisando os resultados, percebi algumas particularidades em seu comportamento. Em problemas de baixa dimensionalidade, os resultados apresentam maior variação. Isso é especialmente evidente na função discreta "Megacity", em que o algoritmo apresenta uma dispersão ainda maior dos valores. Essa função é extremamente desafiadora para algoritmos de otimização e o aprisionamento em extremos locais é mais regra do que exceção.

Em problemas de alta dimensionalidade, o SRA apresenta resultados um pouco abaixo do esperado. Isso provavelmente se deve ao fato de que, em espaços multidimensionais, é necessário um ajuste mais preciso dos parâmetros de temperatura e de taxa de resfriamento para melhorar as soluções mais fracas.

Ainda assim, considero o SRA um algoritmo promissor, com potencial para evoluir. Sua metáfora culinária não apenas torna o conceito intuitivo, mas também possibilita modificações criativas, como o aprimoramento do mecanismo de mutação adaptativa e a realização de experimentos com diferentes esquemas de seleção de "pratos-doadores".

Ao criar o Algoritmo do Restaurateur de Sucesso, não foi minha intenção superar os métodos já existentes, mas sim revelar novos horizontes conceituais através de uma metáfora de vida original. Os resultados obtidos demonstram de forma convincente que esta abordagem merece um lugar no ecossistema dos algoritmos meta-heurísticos.

Surpreendentemente, a ideia de se focar na pior solução da população e de a usar como base para experimentos mostrou-se bastante produtiva, apesar de, à primeira vista, poder parecer absurda. No entanto, é precisamente este princípio de "reabilitação dos azarões" que revela um potencial notável para a otimização. Tal como um restaurador experiente consegue transformar um prato pouco popular num futuro sucesso, o algoritmo consegue converter soluções fracas em versões mais eficazes, aproveitando os "ingredientes" fornecidos pelas soluções líderes.

Esta experiência confirma uma regra valiosa no campo da investigação científica: mesmo as ideias menos ortodoxas, quando bem implementadas, podem proporcionar vantagens práticas. As abordagens fora do padrão frequentemente revelam aspetos de um problema que permanecem invisíveis sob metodologias tradicionais.

Tab

Figura 2. Gradação de cores dos algoritmos conforme os testes correspondentes

Chart

Figura 3. Histograma dos resultados de teste dos algoritmos (em uma escala de 0 a 100, quanto maior, melhor, onde 100 é o resultado teórico máximo possível, no arquivo está o script para cálculo da tabela de classificação)

Prós e contras do algoritmo SRA:

Prós:

  1. Implementação simples.
  2. Bons resultados.

Contras:

  1. Sem desvantagens relevantes.

Está anexado ao artigo um arquivo com as versões atualizadas dos códigos dos algoritmos. O autor não se responsabiliza pela descrição absolutamente fiel dos algoritmos canônicos, já que muitos deles foram modificados para ampliar sua capacidade de busca. As conclusões e opiniões apresentadas baseiam-se nos resultados obtidos durante os experimentos.


Programas utilizados no artigo

# Nome Tipo Descrição
1 C_AO.mqh
Arquivo incluído
Classe principal 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 do ambiente de teste
5
Utilities.mqh
Arquivo incluído
Biblioteca de funções auxiliares
6
CalculationTestResults.mqh
Arquivo incluído
Script para calcular resultados e gerar a tabela comparativa
7
Testing AOs.mq5
Script Ambiente unificado de testes 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
Test_AO_SRA.mq5
Script Ambiente de testes específico para o SRA

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

Arquivos anexados |
SRA.ZIP (172.76 KB)
Gerente de risco profissional remoto para Forex em Python Gerente de risco profissional remoto para Forex em Python
Criamos um gerente de risco profissional remoto para Forex em Python e o implantamos em um servidor, passo a passo. Ao longo do artigo, veremos como gerenciar riscos no Forex de maneira programada e como evitar a perda total do depósito.
Negociando com o Calendário Econômico MQL5 (Parte 4): Implementando Atualizações de Notícias em Tempo Real no Painel Negociando com o Calendário Econômico MQL5 (Parte 4): Implementando Atualizações de Notícias em Tempo Real no Painel
Este artigo aprimora nosso painel do Calendário Econômico implementando atualizações de notícias em tempo real para manter as informações de mercado atuais e acionáveis. Integramos técnicas de busca de dados ao vivo no MQL5 para atualizar os eventos no painel continuamente, melhorando a capacidade de resposta da interface. Essa atualização garante que possamos acessar as últimas notícias econômicas diretamente do painel, otimizando as decisões de negociação com base nos dados mais recentes.
Arbitragem Forex: painel de avaliação de correlações Arbitragem Forex: painel de avaliação de correlações
Vamos analisar a criação de um painel de arbitragem na linguagem MQL5. Como obter taxas de câmbio justas no Forex de diferentes maneiras? Criaremos um indicador para medir os desvios dos preços de mercado em relação às taxas justas, bem como para avaliar o potencial de lucro em rotas de arbitragem entre moedas (como na arbitragem triangular).
Utilizando o modelo de Machine Learning CatBoost como Filtro para Estratégias de Seguimento de Tendência Utilizando o modelo de Machine Learning CatBoost como Filtro para Estratégias de Seguimento de Tendência
CatBoost é um poderoso modelo de machine learning baseado em árvores que se especializa em tomada de decisão com base em features estacionárias. Outros modelos baseados em árvores como XGBoost e Random Forest compartilham características semelhantes em termos de robustez, capacidade de lidar com padrões complexos e interpretabilidade. Esses modelos têm uma ampla gama de usos, desde análise de features até gestão de risco. Neste artigo, vamos percorrer o procedimento de utilização de um modelo CatBoost treinado como filtro para uma estratégia clássica de seguimento de tendência com cruzamento de médias móveis.