Championnat d'optimisation des algorithmes. - page 53

 
Andrey Dik:

Script de test sur la première version de l'algorithme:

Pour une fonction aussi simple, vous avez trop compliqué l'interface. Beaucoup d'exportations inutiles, alors que les choses nécessaires sont absentes. Je n'arrive pas à comprendre votre code tout de suite, je peux imaginer ce que ressentent les personnes qui ne sont pas très douées en programmation.

Je vais maintenant réfléchir et proposer ma propre version de l'exportation simplifiée et du fonctionnement du script de test.

 

L'approche "évolutive" de la recherche des valeurs des paramètres de l'équation FF n'a peut-être pas pour but d'améliorer l'efficacité de la recherche des valeurs, mais plutôt de modéliser le processus d'évolution.

Eh bien, comme l'évolution est représentée par des scientifiques...

L'approche est très cohérente dans sa conformité à tous les canons de l'évolution...

 

Proposition :

1. Une fonction de fitness prend un tableau de paramètres de type double et renvoie un nombre d'autant plus grand que les paramètres sont bien choisis. Le prototype de la fonction de fitness est le suivant :

double FF(double &array[]);

2. La fonction de fitness possède quelques paramètres, qui sont spécifiés dans la structure FitnessParams. Une description de la structure est donnée ci-dessous :

//+------------------------------------------------------------------+
//| Параметры фитнес-функции (FF)                                    |
//+------------------------------------------------------------------+
struct FitnessParams
{
   int      limit_runs;          // Максимально допустимое количество вызовов FF
   int      count_params;        // Количество параметров, которое необходимо оптимизировать
   int      current_runs;        // Текущее количество вызовов функции
   double   current_max_value;   // Текущее найденное максимальное значение
   double   step_value;          // Минимальный шаг изменения параметра. 
   double   max_value;           // Максимальное значение, которое может принимать параметр
   double   min_value;           // Минимальное значение, которое может принимать параметр
   FitnessParams(void);
};
//+------------------------------------------------------------------+
//| Инициализация параметров фитнес-функции (FF) по-умолчанию        |
//+------------------------------------------------------------------+
FitnessParams::FitnessParams(void) : limit_runs(1000),
                                   count_params(2),
                                   step_value(0.1),
                                   max_value(10.0),
                                   min_value(-10.0),
                                   current_runs(0)
                                   
{
   current_max_value = min_value;
}

3. La fonction d'aptitude et ses paramètres sont protégés de toute influence extérieure et sont stockés dans une bibliothèque indépendante..\Scripts\\\FF.ex5. Les valeurs des paramètres de la fonction d'aptitude et de son algorithme lui-même sont fixées au moment de la compilation par un arbitre indépendant et ne peuvent plus être modifiées par quiconque.

4. Un algorithme d'optimisation personnalisé et un script de vérification peuvent trouver les paramètres d'une fonction de fitness. À cette fin, le fichier Export.mqh contient les prototypes nécessaires de cette fonction et ses paramètres. Pour obtenir les paramètres FF, la fonction d'exportation, qui se trouve également dans ...\Scripts\\FF.ex5, est utilisée :

void   GetFitnessParams(FitnessParams& params);

5. L'algorithme d'optimisation de l'utilisateur se trouve dans une bibliothèque utilisateur distincte et fermée..\Scripts\\\\N\N\N\N\N\N\N\N\N\N\N-UserFindExtremum.ex5 et est compilé séparément, du côté de l'utilisateur. La fonction FindExtremum doit être exportée vers la bibliothèque utilisateur. Cette fonction sera appelée par le script de vérification. Le prototype complet de la fonction est donné ci-dessous :

//+------------------------------------------------------------------+
//| Экспорт пользовательской библиотеки поиска экстремума            |
//+------------------------------------------------------------------+
#import "..\\Scripts\\FF\\UserFindExtremum.ex5"
   void FindExtremum(void);
#import

6. Le script de vérification charge dans son espace d'adressage la bibliothèque de la fonction de fitness ..\Scripts\\\\\FF\FF.ex5 avec ses paramètres, et la bibliothèque de la fonction membre Find Extremum..\Scripts\\\FF\UserFindExtremum.ex5. Ensuite, il appelle la fonction membre FindExtremum.

7. après l'exécution de la fonction de participant, le script de vérification interroge les paramètres de la fonction de fitness, qui contiennent la valeur maximale trouvée par la fonction de participant et le nombre d'appels nécessaires pour trouver ce maximum. Sur la base de ces données, un rapport sur le résultat du participant est généré sous la forme d'un tableau :

2016.06.22 13:09:48.583 TestFF (EURUSD,H1)      ———————————————————————————————————————————
2016.06.22 13:09:48.583 TestFF (EURUSD,H1)      Максимальное найденное значение: 3.1
2016.06.22 13:09:48.583 TestFF (EURUSD,H1)      Досрочное выполнение алгритма: НЕТ
2016.06.22 13:09:48.583 TestFF (EURUSD,H1)      Вызовов фитнес-функции потребовалось: 1001
2016.06.22 13:09:48.583 TestFF (EURUSD,H1)      Поиск экстремума выполнен за 0 мсек.

Lepost suivant ajoutera les fichiers nécessaires et un exemple d'utilisation.

 

Fichier Export.mqh - liste des fonctions disponibles et structure des paramètres communs à tous les participants.

//+------------------------------------------------------------------+
//|                                                       Export.mq5 |
//|                                 Copyright 2016, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Vasiliy Sokolov."
#property link      "https://www.mql5.com/ru/users/c-4"
//+------------------------------------------------------------------+
//| Параметры фитнес-функции (FF)                                    |
//+------------------------------------------------------------------+
struct FitnessParams
{
   int      limit_runs;          // Максимально допустимое количество вызовов FF
   int      count_params;        // Количество параметров, которое необходимо оптимизировать
   int      current_runs;        // Текущее количество вызовов функции
   double   current_max_value;   // Текущее найденное максимальное значение
   double   step_value;          // Шаг значений или дискретность. 
   double   max_value;           // Максимальное значение, которое может принимать ff-функция
   double   min_value;           // Минимальное значение, которое может принимать ff-функция
   FitnessParams(void);
};
//+------------------------------------------------------------------+
//| Инициализация параметров фитнес-функции (FF) по-умолчанию        |
//+------------------------------------------------------------------+
FitnessParams::FitnessParams(void) : limit_runs(1000),
                                   count_params(2),
                                   step_value(0.1),
                                   max_value(10.0),
                                   min_value(-10.0),
                                   current_runs(0)
                                   
{
   current_max_value = min_value;
}
//+------------------------------------------------------------------+
//| Экспорт библиотеки фитнесс-функций                               |
//+------------------------------------------------------------------+
#import "..\\Scripts\\FF\\FF.ex5"
   double FF(double &array[]);                       // Фитнес-функция, возвращающая значение тем больше, чем лучше подобраны значения в массиве array
   void   GetFitnessParams(FitnessParams& params);   // Возвращает параметры фитнесс-функции в виде структуры FitnessParams
#import
//+------------------------------------------------------------------+
//| Экспорт пользовательской библиотеки поиска экстремума            |
//+------------------------------------------------------------------+
#import "..\\Scripts\\FF\\UserFindExtremum.ex5"
   void FindExtremum(void);
#import

Fichier FF.mq5 - exemple d'une fonction de fitness en bibliothèque.

//+------------------------------------------------------------------+
//|                                                           FF.mq5 |
//|                                 Copyright 2016, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Vasiliy Sokolov."
#property link      "https://www.mql5.com/ru/users/c-4"
#property library
#property strict
#include "Export.mqh"
//+------------------------------------------------------------------+
//| Параметры фитнесс-функции, с которыми необходимо ознакомится     |
//| алгоритму поиска до начала работы. Получить эти параметры можно  |
//| с помощью функции GetFitnessParams                               |
//+------------------------------------------------------------------+
static FitnessParams FParams;
//+------------------------------------------------------------------+
//| Фитнес-функция, возвращающая значение тем больше, чем лучше      |
//| подобраны значения в массиве array                               |
//+------------------------------------------------------------------+
double FF(double &array[]) export
{ 
   if(FParams.current_runs > FParams.limit_runs)
      return FParams.min_value;
   FParams.current_runs++;
   if(ArraySize (array) < FParams.count_params)
      return FParams.min_value; 
   double ff_value = (-(pow (2.4 + array [0], 2.0) + pow (array [1] - 2.3, 2.0))+3.1415926);
   if(ff_value > FParams.current_max_value)
      FParams.current_max_value = ff_value;
   return ff_value;
}
//+------------------------------------------------------------------+
//| Возвращает параметры фитнесс-функции                             |
//+------------------------------------------------------------------+
void GetFitnessParams(FitnessParams& params)export
{
   params = FParams;
}
//+------------------------------------------------------------------+

Fichier TestFF.mq5 - algorithme de vérification sous forme de script

//+------------------------------------------------------------------+
//|                                                       TestFF.mq5 |
//|                                 Copyright 2016, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include "Export.mqh"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   uint begin_tiks = GetTickCount();
   // Вызываем пользовательскую функцию поиска экстремума фитнес-функции
   FindExtremum();            
   uint end_tiks = GetTickCount();
   // Получаем результаты поиска в качестве комплексного параметра
   FitnessParams params;      
   GetFitnessParams(params);
   // Подготавливаем отчет
   string yesno_count = params.current_runs >= params.limit_runs ? "НЕТ" : "ДА";
   printf("Поиск экстремума выполнен за " + (string)(end_tiks - begin_tiks) + " мсек.");
   printf("Вызовов фитнес-функции потребовалось: " + (string)params.current_runs);
   printf("Досрочное выполнение алгритма: " + yesno_count);
   printf("Максимальное найденное значение: " + DoubleToString(params.current_max_value, 1));
   printf("——————————————————————");
}
//+------------------------------------------------------------------+

Fichier UserFindExtremum.mq5 - fonction personnalisée pour la recherche d'un extremum sous la forme d'une bibliothèque. Une recherche aléatoire est utilisée à titre d'exemple

//+------------------------------------------------------------------+
//|                                             UserFindExtremum.mq5 |
//|                                 Copyright 2016, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property library
#property strict
#include "Export.mqh"
//+------------------------------------------------------------------+
//| Алгоритм поиска экстремума, который будет вызван проверяющим    |
//| скриптом                                                         |
//+------------------------------------------------------------------+
void FindExtremum(void)export
{
   FitnessParams params;
   while(params.current_runs < params.limit_runs)
   {
      GetFitnessParams(params);
      if(params.current_max_value >= params.max_value)
         break;
      double values[];
      ArrayResize(values, params.count_params);
      for(int i = 0; i < params.count_params; i++) 
      {
        double random = RandomDouble(params.min_value, params.max_value);
        values[i] = SeInDiSp (random, params.min_value, params.max_value, params.step_value);
      }
      FF(values);
   }
}
//+------------------------------------------------------------------+
//| Выбор в дескретном пространстве                                  |
//+------------------------------------------------------------------+
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 RandomDouble(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)));
}
Dossiers :
Export.mqh  3 kb
FF.mq5  2 kb
TestFF.mq5  2 kb
 
Vasiliy Sokolov:

Fichier Export.mqh - liste des fonctions disponibles et structure des paramètres communs à tous les participants.

Fichier FF.mq5 - exemple d'une fonction de fitness en bibliothèque.

Fichier TestFF.mq5 - algorithme de vérification sous forme de script

Fichier UserFindExtremum.mq5 - fonction personnalisée pour la recherche d'un extremum sous la forme d'une bibliothèque. Une recherche aléatoire est utilisée à titre d'exemple

Tous les exemples sont très clairs et compréhensibles. Merci beaucoup pour votre travail. )
 
Vasiliy Sokolov:

Pour une fonction aussi simple, vous avez trop compliqué l'interface. Beaucoup d'exportations inutiles, alors que les choses nécessaires au contraire manquent. Je n'ai pas compris votre code depuis la première fois, je peux imaginer ce que ressentent les personnes qui ne sont pas très douées en programmation.

Je vais y réfléchir et proposer ma propre version du script d'exportation et de test simplifié.

Pourquoi n'est-ce pas nécessaire ?

Quel genre de choses manque-t-il ?

Après tout, il ne s'agit pas seulement de rendre la vie aussi difficile que possible aux participants ; j'ai donc tout fait, et je n'ai pas pensé à tout le premier jour, ni même au deuxième.

 
Andrey Dik:

Pourquoi pas les bons ?

Lesquelles sont manquantes ?

Après tout, il ne s'agit pas seulement de rendre la vie des participants aussi difficile que possible. J'ai donc tout fait, et je n'ai pas pensé à tout le premier jour, ni même au deuxième.

Andrew, je ne sais pas pour les autres, mais personnellement, j'ai préféré l'exemple de Vassili. Sans vouloir vous offenser. Ce n'est que ma perception subjective.

Pour être juste, je propose de soumettre au vote la question du choix de l'interface de connexion (la vôtre ou celle de Vasiliy).

Qu'en pensez-vous ?

 
Реter Konow:

Andrew, je ne sais pas pour les autres, mais personnellement, je préférais l'exemple de Vasily. Sans vouloir vous offenser. C'est juste ma perception subjective...

Pour être juste, je propose de soumettre au vote la question du choix de l'interface de connexion (la vôtre ou celle de Vasiliy).

Qu'en pensez-vous ?

Qu'est-ce que vous préférez exactement ?
Et l'exemple de Vassily sur le deuxième type de connexion, et où sur le premier ?
 
Andrey Dik:

Pourquoi pas les bons ?

Lesquelles sont manquantes ?

Il ne s'agit pas seulement de rendre la vie aussi difficile que possible aux participants ; c'est ainsi que j'ai procédé, et ce n'est pas le premier jour que j'y ai pensé, ni même le deuxième.

Dans votre exemple, la tâche de recherche est partiellement déléguée au script du vérificateur. Ceci est incorrect. Le script du vérificateur doit appeler la recherche et vérifier son résultat et rien d'autre.

Tous les paramètres FF ne sont pas disponibles. Par exemple, comment obtenir le pas de paramètre (valeur 0.1), le maximum et le minimum possibles ? C'est bien sûr génial que chaque utilisateur lise ce forum et comprenne que le pas s'avère être 0,1, le minimum -10,0 et le maximum +10,0, puis entre ces constantes dans son code et espère que la fonction FF pense de la même manière. Mais ce n'est pas la bonne façon de le faire.

De nombreuses fonctions d'exportation, comme ServiceFunc1, ne sont utilisées que dans des algorithmes de recherche spécifiques. Par exemple, ils ne doivent pas être utilisés pour la recherche aléatoire. Alors pourquoi une bibliothèque d'utilisateurs devrait-elle les exporter ? Il suffit de séparer la tâche de test de la tâche de recherche pour se rendre compte que toute cette combinaison compliquée de fonctions d'exportation est inutile.

Il y a beaucoup d'autres choses qui rendent les add-ons inutiles.

 
Andrey Dik:
Qu'est-ce que vous préférez exactement ?
Et Basil est un exemple du second type de connexion, et où sur le premier ?
Vous n'avez pas besoin du deuxième, troisième, 110 type de connexion. Vous n'en avez besoin que d'un seul, mais d'un type de connexion universel. Sans utiliser de constructions syntaxiques inutiles. Personne n'a envie de s'interroger sur la signification abrégée de la fonction ServiceFunc1. Il faut plutôt donner une fonction de fitness et des règles pour remplir ses paramètres. Et rien d'autre.