Campeonato de optimización de algoritmos. - página 52

 

¿Por qué importar en el segundo ejemplo?

//+------------------------------------------------------------------+
// тестовая фитнес функция чемпионата, не известна участникам
#import "\\Projects\\OAC\\lib\\ff.ex5"
// запросить количество параметров ФФ 
int    GetParamCountFF (); 
// запуск ФФ, получеие значения соответствующее параметроам ФФ
double FF (double &array []); 
// произведённое количество запусков ФФ
int    GetCountRunsFF (); 
#import
 
Dmitry Fedoseev:

Bueno, yo también podría escribir eso, ¿qué es lo que no está claro en mi pregunta?

Era más bien una pregunta retórica, porque estoy seguro de que lo entiendes.

Dmitry Fedoseev:
¿Por qué tengo que hacer una pregunta 10 veces?

Es una pregunta difícil, a menudo me pregunto lo mismo).

DmitryFedoseev:

¿Por qué necesitas importar en el segundo ejemplo?

Para controlar el algoritmo desde el script, cuántas veces el algoritmo realmente llamó al FF.

Para la primera variante es claramente visible, porque el propio script hace las llamadas, pero para la segunda variante no es visible, por lo que necesitamos la capacidad de acceder a la biblioteca FF desde el script.

 

Ahora, quiero dirigirme a todos los participantes, que se consideran "novatos" en este tema y no esperan seriamente ganar.

Si dejamos de lado toda la insana "teoría" sobre las múltiples dimensiones del espacio, que tanto confunde el problema, y acudimos a las matemáticas puras, vemos que el FF es una ecuación.

Esta ecuación se convierte en una función analítica sólo si se aplica a una gráfica.

Pero hay una pregunta: ¿debería serlo? Un gráfico simplemente ayuda a visualizar la relación entre los parámetros de la ecuación.

Tras 158 páginas de discusión, ya podemos formular la esencia del problema:

Tenemos que encontrar los valores de las variables del lado derecho de la ecuación en los que el valor de la variable del lado izquierdo de la ecuación es mayor.

El objetivo es tratar de hacerlo de forma más eficiente que una fuerza bruta completa.

Eso es todo.

Siguiente:

Para resolver este problema, se inventó una técnica "evolutiva" de búsqueda de valores. Se construyeron analogías y métodos procedentes del darwinismo.

La cuestión de la eficacia de este enfoque es discutible. Probablemente, hay formas más sencillas y eficaces de resolver este problema.

Mi práctica demuestra que los enfoques generalmente aceptados no siempre son los más eficaces.

Seguro que podemos sortear a los "evolucionistas" bastante bien...

Intentémoslo.

 

Un ejemplo del algoritmo del participante para la segunda variante de llamar a la FF:

#property library
#property strict

//+------------------------------------------------------------------+
// тестовая фитнес функция чемпионата, не известна участникам
#import "\\Projects\\OAC\\lib\\ff.ex5"
// запросить количество параметров ФФ 
int    GetParamCountFF (); 
// запуск ФФ, получеие значения соответствующее параметроам ФФ
double FF (double &array []); 
// произведённое количество запусков ФФ
int    GetCountRunsFF (); 
#import
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
void InitAO (int paramCount, int maxFFruns) export
{
  params = paramCount;
  maxFFrunsPossible = maxFFruns;
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
void StartAlgo () export
{
  double param []; 
  ArrayResize (param, params);
  double ffVolue = 0.0; 
  
  //------------------------------------------------------------------
  for(int i=0; i< maxFFrunsPossible; i++) 
  {
    GenerateParam (param);
    ffVolue = FF(param);
    if(ffVolue > maxFFvolue) 
      maxFFvolue = ffVolue;
  }
  //------------------------------------------------------------------
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
double GetMaxFF () export
{
  return(maxFFvolue);
}
//+------------------------------------------------------------------+

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Все функции выше этой строки - обязательны! Именно они будут импортированы 
// и использованы тестовым скриптом. Они нужны для доступа к алгоритму оптимизации.
// Содержимое - произвольное, на усмотрение участника
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Ниже этой строки пример алгоритма оптимизации участника
//————————————————————————————————————————————————————————————————————
int    params     = 0;
int    maxFFrunsPossible = 0;
double maxFFvolue = - DBL_MAX;
double minParam   = -10.0;
double maxParam   = 10.0;
double stepParam  = 0.1;
//————————————————————————————————————————————————————————————————————

//————————————————————————————————————————————————————————————————————
// Генерация значений оптимизируемых параметров
void GenerateParam (double &param[])
{
  int size = ArraySize (param);
  double paramVolue = 0.0;
  for(int i = 0; i < size; i++) 
  {
    paramVolue = RNDfromCI (minParam, maxParam);
    param [i] = SeInDiSp (paramVolue, minParam, maxParam, stepParam); 
  }
}
//————————————————————————————————————————————————————————————————————

//————————————————————————————————————————————————————————————————————
// Выбор в дискретном пространстве
double SeInDiSp (double in, double inMin, double inMax, double step) 
{ 
  if(in <= inMin) 
    return (inMin); 
  if(in >= inMax) 
    return (inMax); 
  if(step == 0.0) 
    return (in); 
  else 
    return (inMin + step * (double)MathRound ((in - inMin) / step));
}
//————————————————————————————————————————————————————————————————————

//————————————————————————————————————————————————————————————————————
// ГСЧ в заданном интервале
double RNDfromCI (double min, double max) 
{ 
  if(min == max) 
    return (min); 
  double Min, Max; 
  if(min > max) 
  {
    Min = max; 
    Max = min;
  }
  else 
  {
    Min = min; 
    Max = max;
  }
  return (double(Min + ((Max - Min) * (double)MathRand () / 32767.0)));
}
//————————————————————————————————————————————————————————————————————

El código básico del algoritmo es el mismo que en la primera variante, pero llamando al FF desde el algoritmo en vez de desde el script.

Naturalmente, los resultados son similares a los de la primera variante:

2016.06.22 11:47:45.321 OAC variante 2 (GBPUSD,M30) ---------------------------------

2016.06.22 11:47:45.321 OAC variante 2 (GBPUSD,M30) Tiempo: 135 µs; 0.00013500 c

2016.06.22 11:47:45.321 OAC variante 2 (GBPUSD,M30) FF Ejecuta: 1000

2016.06.22 11:47:45.321 OAC variante 2 (GBPUSD,M30) Max: 2.94159260

2016.06.22 11:47:41.404 OAC variante 2 (GBPUSD,M30) ---------------------------------

2016.06.22 11:47:41.404 OAC variante 2 (GBPUSD,M30) Tiempo: 136 µs; 0.00013600 c

2016.06.22 11:47:41.404 OAC variante 2 (GBPUSD,M30) FF Runs: 1000

2016.06.22 11:47:41.404 OAC variante 2 (GBPUSD,M30) Max: 3.10159260

2016.06.22 11:47:37.309 OAC variante 2 (GBPUSD,M30) ---------------------------------

2016.06.22 11:47:37.309 OAC variante 2 (GBPUSD,M30) Tiempo: 133 µs; 0.00013300 c

2016.06.22 11:47:37.309 OAC variante 2 (GBPUSD,M30) FF Ejecuta: 1000

2016.06.22 11:47:37.309 OAC variante 2 (GBPUSD,M30) Max: 3.06159260

2016.06.22 11:47:32.933 OAC variante 2 (GBPUSD,M30) ---------------------------------

2016.06.22 11:47:32.933 OAC variante 2 (GBPUSD,M30) Tiempo: 133 µs; 0.00013300 c

2016.06.22 11:47:32.933 OAC variante 2 (GBPUSD,M30) FF Ejecuta: 1000

2016.06.22 11:47:32.933 OAC variante 2 (GBPUSD,M30) Max: 3.10159260

2016.06.22 11:47:07.584 OAC variante 2 (GBPUSD,M30) ---------------------------------

2016.06.22 11:47:07.584 OAC variante 2 (GBPUSD,M30) Tiempo: 180 µs; 0.00018000 c

2016.06.22 11:47:07.584 OAC variante 2 (GBPUSD,M30) FF corre: 1000

2016.06.22 11:47:07.584 OAC variante 2 (GBPUSD,M30) Max: 3.04159260

Es decir, no está nada mal.

 

Así, los ejemplos anteriores muestran la forma en que los algoritmos de los participantes se conectan a los scripts de prueba mediante la importación de funciones.

Permítanme recordarles por qué se organiza exactamente esta forma de trabajar con los algoritmos de los participantes: es necesario, por un lado, ocultar el algoritmo del participante para proteger la propiedad intelectual y, por otro, permitir el control y la verificación tanto de los miembros del jurado como de los espectadores.

 

Lo probaré hoy.

Pero sería recomendable recopilar (entiendo, Andrei, que tenías prisa) y en un solo post, publicar las normas relativas a los expedientes, con archivos adjuntos de estos mismos expedientes. No necesariamente ahora, sino para tener un punto de partida.

 
Реter Konow:

Ahora, quiero hacer un llamamiento a todos los participantes, que se consideran "novatos" en este tema y no esperan seriamente ganar.

Si dejamos de lado toda la "teoría" descabellada sobre las múltiples dimensiones del espacio, que confunde enormemente un problema ya de por sí confuso, y recurrimos a las matemáticas puras, vemos que el FF es una ecuación.

Esta ecuación se convierte en una función analítica sólo si se aplica a una gráfica.

Un gráfico simplemente ayuda a visualizar los patrones de relación de los parámetros de la ecuación.

Tras 158 páginas de discusión, ya podemos formular la esencia del problema:

Tenemos que encontrar los valores de las variables del lado derecho de la ecuación en los que el valor de la variable del lado izquierdo de la ecuación es mayor.

El objetivo es tratar de hacerlo de forma más eficiente que una fuerza bruta completa.

Eso es todo.

Siguiente:

Para resolver este problema, se inventó una técnica "evolutiva" de búsqueda de valores. Se construyeron analogías y métodos procedentes del darwinismo.

La cuestión de la eficacia de este enfoque es discutible. Probablemente, hay formas más sencillas y eficaces de resolver este problema.

Mi práctica demuestra que los enfoques generalmente aceptados no siempre son los más eficaces.

Seguro que podemos sortear a los "evolucionistas" bastante bien...

Intentémoslo.

Si dejas de lado la connotación emocional del post, lo que has dicho es básicamente cierto. Lo único que has omitido mencionar es que la ecuación FF en sí misma es desconocida dentro de este campeonato (en la vida puede ser conocida o no).

Sobre las "teorías no ficticias" - he dado en este hilo pistas claras sobre los principios del algoritmo de optimización que no se utilizan en ningún otro sitio y que nunca se han utilizado antes (al menos en las fuentes disponibles). Y la elección depende siempre del investigador: cómo y qué utilizará en el algoritmo. En el ejemplo anterior hay un algoritmo que no tiene nada que ver con Darwin ni siquiera indirectamente. Hay un montón de métodos de optimización y nadie, al menos yo no he afirmado que "originario de Darwin" sea mejor.

Así que, ¡buena suerte a los principiantes! ¡Adelante, a la victoria!

 
No he codificado en un cinco y tampoco tengo experiencia en operaciones de exportación/importación. Por favor, dígame si he entendido bien su ejemplo. He puesto mis comentarios en el código. Otra pregunta . Si el FF viene dado por una fórmula, habrá operaciones de división o extracción de raíces. Un valor cero o negativo provocará un error crítico y detendrá el programa.
// -- данный код находится на стороне жюри (организатора)---------------------
#property library    //EX5-файл будет являться библиотекой
#property strict
int  countRuns    = 0;  // число обращений к ФФ. Фитнес функции это, как я понимаю неизвестная никому функция у которой 500 параметров
 // и нужно найти такие значения параметров при которой значение фф= максимальному 
//+------------------------------------------------------------------+
int GetParamCountFF () export //функция задачи участникам количества параметров фф  модификатор export указывает что функция доступна
// алгоритму участника  
{ 
  return (2);// возвращает количество параметров участнику 2 для данного примера 
  // участник в своём коде прописывает  int NumberParam=GetParamCountFF();
}

double FF (double &array []) export // сама фф 
{ 
  countRuns++;
  int sizeArray = ArraySize (array);//количество элементов массива
  //-------дальше не пойму логику----------------- 
  if(sizeArray != 2) 
    return (-DBL_MAX); 
  return (-(pow (2.4 + array [0], 2.0) + pow (array [1] - 2.3, 2.0))+3.1415926);
 //--------------вероятно нужно так --------------
    if(sizeArray != 2){ // возвращает минимальное double ( или может лучше ошибку)
    // если количество элементов в массиве пользователя не равно заданному)
    return (-DBL_MAX);
    } 
    else{ // возвращает значение функции
  return (-(pow (2.4 + array [0], 2.0) + pow (array [1] - 2.3, 2.0))+3.1415926);
  }
  //------------------------------------------------------------------
}

int GetCountRunsFF () export
{ 
  return (countRuns);// возвращает кол. обращений к фф
}
 
Yuri Evseenkov:
No codifico en A y no tengo experiencia en operaciones de exportación e importación. Por favor, dígame si he entendido bien su ejemplo. He puesto mis comentarios en el código. Otra pregunta . Si el FF se da por fórmula, habrá operaciones de división o extracción de raíces. Un valor cero o negativo provocará un error crítico y detendrá el programa.

Sí, tienes razón al entender cómo funciona el campeonato de FF.

La única corrección sobre la devolución de resultados en caso de tamaño incorrecto de la matriz de parámetros - el algoritmo del participante conoce el número de parámetros del FF y si envía la matriz de tamaño incorrecto al FF, es problema del algoritmo del participante, no del FF. Piense en este punto, si toma el mercado como ejemplo - el mercado nunca le informará de que está utilizando el número "equivocado" de parámetros de estrategia en su comercio, sólo obtendrá un resultado de comercio negativo y eso es todo, sin ninguna explicación del mercado por sus errores.

Puedes sustituir la palabra Vuestro por la palabra Nuestro, y puedes sustituir la palabra Vosotros por Nosotros - nada cambiará y nada seguirá siendo verdad.

 
Igor Volodin:

Lo probaré hoy.

Pero sería recomendable recopilar (entiendo, Andrei, que tenías prisa) y en un solo post, publicar las normas relativas a los expedientes, con archivos adjuntos de estos mismos expedientes. No necesariamente ahora, sino para tener un punto de partida.

Probablemente, sería conveniente poner los archivos de los ejemplos en un almacén de archivos accesible, para no tener que saltar en su búsqueda, y colocar un enlace al almacén al principio de la rama.

Sí, lo haré.