Чемпионат Алгоритмов Оптимизации. - страница 53

 
Andrey Dik:

Тестовый скрипт по первому варианту исполнения алгоритма:

Для такой простой функции, Вы чересчур усложнили интерфейс. Много ненужного экспорта, а нужных вещей наоборот не хватает. Разобрался в Вашем коде не с первого раза, представляю что чувствуют люди не так хорошо владеющие программированием. 

Сейчас подумаю и предложу свой вариант упрощенного экспорта и работы тестового скрипта. 

 

Возможно, "эволюционный" подход нахождения значений параметров уравнения ФФ, создан не столько с целью повышения эффективности поиска значений, сколько для программного моделирования процесса эволюции.

Ну в том виде, каком эволюцию представляют ученые...

Уж больно подход последователен в своем соответствии всем эволюционным канонам...

 

Пропозиция:

1. фитнес-функция принимает массив параметров типа double и возвращает число тем больше, чем лучше подобраны параметры. Прототип фитнес-функции следующий:

double FF(double &array[]);

2. Фитнес-функция обладает определенными параметрами, которые указываются в структуре FitnessParams. Описание структуры дано ниже:

//+------------------------------------------------------------------+
//| Параметры фитнес-функции (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. Фитнес функция и ее параметры защищены от внешнего воздействия и находятся в независимой библиотеке ..\\Scripts\\FF\\FF.ex5 Значения параметров фитнес-функции, как и сам ее алгоритм задается в момент комплиляции независимым рефери и больше не может быть кем-либо изменен.

4. Пользовательский алгоритм оптимизации и проверяющий скрипт могут узнать параметры фитнес-функции. Для чего в файле Export.mqh содержаться необходимые прототипы этой функции и ее параметров. Для получения параметров FF используется функция экспорта параметров, также размещенная в ..\\Scripts\\FF\\FF.ex5:

void   GetFitnessParams(FitnessParams& params);

5. Пользовательский алгоритм оптимизации находится в отдельной, закрытой пользовательской библиотеки ..\\Scripts\\FF\\UserFindExtremum.ex5 и компилируется отдельно, на стороне пользователя. В библиотеке пользователя должна быть экспортирована функция FindExtremum. Эту функцию будет вызывать проверяющий скрипт. Ниже представлен полный прототип функции:

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

6. Проверяющий скрипт загружает в свое адресное пространство библиотеку фитнесс-функции ..\\Scripts\\FF\\FF.ex5 с ее параметрами, и библиотеку участника по поиску экстремума ..\\Scripts\\FF\\UserFindExtremum.ex5. После чего вызывает функцию участника FindExtremum.

7. После отработки функции участника, проверяющий скрипт запрашивает параметры фитнес-функции, в которых содержится максимальное найденное значение функцией участника, а также количество вызовов, которое потребовалось для нахождения этого максимума. На основании этих данных формируется отчет о результате участника в виде таблицы:

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 мсек.

В следующем посте будут приложены необходимые файлы и пример использования 

 

Файл Export.mqh - общий для всех участников список доступных функций и структура параметров

//+------------------------------------------------------------------+
//|                                                       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

Файл FF.mq5 - пример фитнес-функции в виде библиотеки.

//+------------------------------------------------------------------+
//|                                                           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;
}
//+------------------------------------------------------------------+

Файл TestFF.mq5 - проверяющий алгоритм в виде скрипта

//+------------------------------------------------------------------+
//|                                                       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("——————————————————————");
}
//+------------------------------------------------------------------+

Файл UserFindExtremum.mq5 - пользовательская функция поиска экстремума в виде библоитеки. В качестве примера используется случайный поиск

//+------------------------------------------------------------------+
//|                                             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)));
}
Файлы:
Export.mqh  3 kb
FF.mq5  2 kb
TestFF.mq5  2 kb
 
Vasiliy Sokolov:

Файл Export.mqh - общий для всех участников список доступных функций и структура параметров

Файл FF.mq5 - пример фитнес-функции в виде библиотеки.

Файл TestFF.mq5 - проверяющий алгоритм в виде скрипта

Файл UserFindExtremum.mq5 - пользовательская функция поиска экстремума в виде библоитеке. В качестве примера используется случайный поиск

Во всех примерах все очень ясно и понятно описано. Большое спасибо за проделанный труд. )
 
Vasiliy Sokolov:

Для такой простой функции, Вы чересчур усложнили интерфейс. Много ненужного экспорта, а нужных вещей наоборот не хватает. Разобрался в Вашем коде не с первого раза, представляю что чувствуют люди не так хорошо владеющие программированием. 

Сейчас подумаю и предложу свой вариант упрощенного экспорта и работы тестового скрипта. 

Почему не нужных?

Каких нужных не хватает?

Ведь не просто для того, что бы максимально усложнить жизнь участникам так всё я сделал, и не первый день всё обдумывалось и даже не второй.

 
Andrey Dik:

Почему не нужных?

Каких нужных не хватает?

Ведь не просто для того, что бы максимально усложнить жизнь участникам так всё я сделал, и не первый день всё обдумывалось и даже не второй.

Андрей, я не знаю как другие, но лично мне, пример Василия понравился больше. Без обид. Это просто мое субъективное восприятие...

Чтобы было честно, предлагаю поставить вопрос о выборе интерфейса подключения (Вашего или Василия) на голосование.

Как Вы считаете?

 
Реter Konow:

Андрей, я не знаю как другие, но лично мне, пример Василия понравился больше. Без обид. Это просто мое субъективное восприятие...

Чтобы было честно, предлагаю поставить вопрос о выборе интерфейса подключения (Вашего или Василия) на голосование.

Как Вы считаете?

Чем конкретно нравится больше? 
И пример Василия повторому типу подключения, а где по первому? 
 
Andrey Dik:

Почему не нужных?

Каких нужных не хватает?

Ведь не просто для того, что бы максимально усложнить жизнь участникам так всё я сделал, и не первый день всё обдумывалось и даже не второй.

В Вашем примере задача поиска частично делегируется проверяющему скрипту. Это неправильно. Скрипт проверки должен вызвать поиск и проверить его результат и ничего больше.

Не все параметры ФФ доступны. Например, как получить шаг параметров (значение 0.1), возможный максимум и минимум? Это конечно замечательно, что каждый пользователь должен прочитать этот форум и понять, что шаг оказывается равен 0.1, минимум -10.0 а максимум +10.0, после чего ввести эти константы в свой код, после чего надеятся, что ФФ функция думает также. Но по-хорошему так не делается.

Многие экспортные функции, вроде ServiceFunc1 используются лишь в специфических алгоритмах поиска. Например в случайном поиске их юзать не надо. Тогда зачем пользовательская библиотека должна их экспортировать? Достаточно разделить задачу тестирования с задачей непосредственного поиска что бы понять, что вся эта сложная комбинация экспортных функций просто не нужна. 

Есть еще много моментов, которые делают не нужные надстройки.

 
Andrey Dik:
Чем конкретно нравится больше? 
И пример Василия повторому типу подключения, а где по первому? 
Не нужен второй, третий, 110 тип подключения. Нужен только один, но универсальный тип подключения. Без использования лишних синтаксических конструкций. Никто не захочет ломать голову над сокральным смыслом функции ServiceFunc1. Вместо этого нужно дать фитнес-функцию и правила заполнения ее параметров. И больше ничего.
Причина обращения: