Discussão do artigo "Métodos de otimização da biblioteca Alglib (Parte II)" - página 2

[Excluído]  

Pesquise a função skin do artigo usando o método lbfgs.




Não entendi de quais mil parâmetros estamos falando. Se tiver um exemplo de uma função desse tipo, compartilhe-o.

 

Não sei de qual Skin estamos falando, mas a função original do teste de Skin e várias outras foram desenvolvidas por @Andrey Dik neste tópico em 2010 e, desde 2020, você pode encontrar e visualizar a fórmula aqui \MQL5\Experts\Examples\Math 3D\Functions.mqh e aqui \MT5\MQL5\Experts\Examples\Math 3D Morpher\Functions.mqh. Essa é uma função interessante, mas simples. Posteriormente, ele desenvolveu outros benchmarks, como Hilly, Forest e Megacity.

Quanto aos testes em funções bidimensionais, e ainda mais em funções unidimensionais, foi dito acima que não há sentido prático, pois a maioria dos AOs as resolve de forma elementar, e até mesmo os algoritmos mais simples com aleatórios (há PRNGs super-rápidos) mostrarão resultados surpreendentemente altos, criando uma ilusão de alta eficiência e velocidade. Portanto, são consideradas dimensões de 10 ou mais. O aumento da dimensionalidade pode ser obtido duplicando benchmarks unidimensionais ou bidimensionais (a soma obtida é dividida pelo número de funções de teste), de modo que o mínimo e o máximo da função de teste sejam sempre conhecidos, independentemente da dimensionalidade. Essa é uma técnica comum para aumentar a dimensionalidade e ainda conhecer de forma confiável a área de definição da função de teste.

Sobre "equalizar". OK, vamos torná-lo igual, mas isso não fará com que eles se sintam melhor. A maioria dos AOs de população se sente bem com um tamanho de população de 50 (alguns menores, por exemplo, 10, alguns maiores, por exemplo, 100), se limitarmos o número de execuções de FF a 10.000 épocas, considerarmos épocas = 10.000 / tamanho da população, obteremos 10.000 / 50 = 200. Portanto, só precisamos executar 50 vezes os métodos de gradiente com diferentes posições iniciais no espaço e obter a melhor solução entre elas, simulando assim a população. E, assim, repetir várias vezes e calcular a média desses melhores valores. Dessa forma, haverá uma completa "igualdade de condições", apenas se antes os métodos tinham a chance de encontrar uma solução em 10.000 iterações, agora haverá 200 iterações, mas 50 tentativas.

Vamos ver o que conseguimos com isso. Vamos corrigir o script deste artigo para que o L-BGFS simule a população.

int epochCount = NumbTestFuncRuns_P / PopSize_P;

  for (int test = 0; test < NumberRepetTest_P; test++)
  {
    double bestInPop = -DBL_MAX; // melhor na população

    for (int p = 0; p < PopSize_P; p++)
    {
      for (int i = 0; i < funcCount; i++)
      {
        x [i * 2] = Ut.RNDfromCI (bndl [i * 2], bndu [i * 2]);
        x [i * 2 + 1] = Ut.RNDfromCI (bndl [i * 2 + 1], bndu [i * 2 + 1]);
      }

      //------------------------------------------------------------------------
      C_OptimizedFunction  fFunc; fFunc.Init (params, epochCount, PopSize_P, clrConv);
      CObject              obj;
      CNDimensional_Rep    frep;
      CMinLBFGSReportShell rep;

      double epsg = 1 e-16;
      double epsf = 1 e-16;

      CAlglib::MinLBFGSCreateF  (1, x, DiffStep_P, fFunc.state);
      CAlglib::MinLBFGSSetCond  (fFunc.state, epsg, epsf, ArgumentStep_P, epochCount);
      CAlglib::MinLBFGSSetScale (fFunc.state, s);
      CAlglib::MinLBFGSOptimize (fFunc.state, fFunc, frep, 0, obj);
      CAlglib::MinLBFGSResults  (fFunc.state, x, rep);
      //------------------------------------------------------------------------

      if (fFunc.fB > bestInPop) bestInPop = fFunc.fB;
    }

    aveResult += bestInPop;
  }

  aveResult /= NumberRepetTest_P;

E obteremos estes resultados:

LBFGS|método BFGS de memória limitada para otimização em larga escala|0.9|
=============================
5 Hilly's; Func runs: 10000; result: 0.52942166492675
25 Hilly's; Func runs: 10000; result: 0.30437018399902754
500 Hilly's; Func runs: 10000; result: 0.253457675831117
=============================
5 Forest's; Func runs: 10000; result: 0.46775770774270276
25 Forest's; Func runs: 10000; result: 0.20030246823425313
500 Forest's; Func runs: 10000; resultado: 0.15436391164477226
=============================
5 Megacity's; Func runs: 10000; resultado: 0.3046153846153846
25 Megacity's; Func runs: 10000; resultado: 0.13384615384615386
500 Megacity's; Func runs: 10000; resultado: 0.09492307692307773
=============================
Pontuação total: 2.44306 (27.15%)

27,15% é aproximadamente o 42º lugar na classificação atual de 45 lugares.

Agora todos estão em igualdade de condições.

Em anexo à postagem está o script para esse teste. Todas as inclusões necessárias podem ser encontradas no arquivo do artigo.

Arquivos anexados:
[Excluído]  
Maxim Dmitrievsky #:

Pesquise o ph-i da pele do artigo usando o método lbfgs.

Não entendi de quais mil parâmetros estamos falando. Se tiver um exemplo de uma função desse tipo, compartilhe-o.

É a mesma do artigo. Extraído do terminal. Ele diz que é uma das mais complicadas. Em seguida, diz que é muito simples.

https://www.mql5.com/ru/forum/118887/page2#comment_3150124

Não está claro qual subpersonalidade levar a sério.

Onde posso encontrar o código de uma função complexa para 1000 parâmetros?

 
Maxim Dmitrievsky #:
Igual ao do artigo. Extraído do terminal. Ele diz que é um dos mais complicados. Em seguida, diz que é muito simples.

h ttps:// www.mql5.com/ru/forum/118887/page2#comment_3150124

Não está claro qual subpersonalidade levar a sério.

Onde posso encontrar o código de uma função complexa para 1000 parâmetros?

Leia com mais atenção, o Hilly foi desenvolvido mais tarde e é mais complexo que o Skin. O Skin pertence ao grupo dos simples (como o Rastrigin e a maioria dos outros famosos), porque 50% da superfície tem exatamente 50% de altura. Tudo está descrito nos artigos.

Todas as fontes necessárias estão no arquivo do artigo, estude-as.

Onde está escrito que ela é "muito" simples?
[Excluído]  
Andrey Dik #:

Leia com mais atenção, o Hilly foi desenvolvido mais tarde e é mais complexo que o Skin. O Skin pertence ao grupo simples (como o Rastrigin e a maioria dos outros famosos), pois 50% da superfície está exatamente a 50% da altura. Tudo isso está descrito nos artigos.

Todas as fontes necessárias estão no arquivo do artigo.

Eu verifico em python, só preciso do código da função, que é complexo.

Eu uso o MQL apenas no nível de abertura e fechamento de negociações.
 
Maxim Dmitrievsky #:

Eu verifico em python, só preciso do código de uma função que é complexa.

Eu uso o MQL apenas no nível de abertura e fechamento de negociações.

Pegue o código Hilly do artigo, execute-o no chat e ele será um código python.

Ou Megacity, que é uma função muito complexa para qualquer AO.

[Excluído]  
Andrey Dik #:

Pegue o código Hilly do artigo, execute-o no chat e ele se transformará em código python.

Ou Megacity, que é muito complexo para qualquer função AO.

E o C_dimentional ou qualquer que seja seu nome, onde obtê-lo? Para ter muitos parâmetros

 
Maxim Dmitrievsky #:

E o C_dimentional ou o que quer que seja, onde você o consegue? Para ter muitos parâmetros.

Aqui está uma nova classe de função de teste de núcleo (o artigo a tem no arquivo):

double CalcFunc (double &args []) //argumentos da função
  {
    int numbOfFunctions = ArraySize (args) / 2;
    if (numbOfFunctions < 1) return GetMinFunValue ();

    double x, y;
    double sum = 0.0;
    for (int i = 0; i < numbOfFunctions; i++)
    {
      x = args [i * 2];
      y = args [i * 2 + 1];

      if (!MathIsValidNumber (x)) return GetMinFunValue ();
      if (!MathIsValidNumber (y)) return GetMinFunValue ();

      //duplo u = 0,5;
      //x = x * cos (u) - y * sin (u);
      //y = x * sin (u) + y * cos (u);

      if (x < GetMinRangeX ()) return GetMinFunValue ();
      if (x > GetMaxRangeX ()) return GetMinFunValue ();

      if (y < GetMinRangeY ()) return GetMinFunValue ();
      if (y > GetMaxRangeY ()) return GetMinFunValue ();

      sum += Core (x, y);
    }
    
    sum /= numbOfFunctions;

    return sum;
  }

Basta lançar uma matriz multidimensional (quero dizer, em uma dimensão da matriz há muitas células, espaço multidimensional) de qualquer dimensionalidade em args, e o método espalhará os argumentos da matriz para funções bidimensionais. É claro que, se você lançar uma matriz com dimensionalidade ímpar, uma célula será descartada e não participará dos cálculos. Ou seja, essa é uma função de teste multidimensional com número par de dimensões.

Vou lançá-la mais tarde com base nas unidimensionais, pois será mais prático e será possível criar gráficos com mais clareza.

O código comentado é a capacidade de girar a função em algum ângulo. Isso é um problema para muitos AOs. Ele ainda não é usado em lugar algum.

 
Seria bom acrescentar ao benchmark o tempo durante o qual o algoritmo resolve o problema. Eu, por exemplo, estou interessado no tempo em primeiro lugar.
 
Evgeniy Chernish #:
Seria bom acrescentar ao benchmark o tempo em que o algoritmo resolve o problema. Eu, por exemplo, estou interessado no tempo em primeiro lugar.
Obrigado, vou considerar essa possibilidade.