算法优化锦标赛。 - 页 53

 
Andrey Dik:

关于第一版算法的 测试脚本。

对于这样一个简单的功能,你把界面弄得过于复杂了。很多不必要的出口,而必要的东西却没有。我不能马上理解你的代码,我可以想象那些不善于编程的人的感受。

现在我将思考并提出我自己版本的简化出口和测试脚本操作。

 

也许寻找FF方程参数值的 "进化 "方法与其说是为了提高寻找数值的效率,不如说是为了对进化的过程进行软件建模。

那么,由于进化论是由科学家代表的...

该方法在符合所有的进化论法则方面非常一致......

 

命题。

1. 一个健身函数接收一个双倍类型的参数数组,并返回一个数字,参数选得越大越好。健身函数的原型如下。

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. 健身函数及其参数受到保护,不受外界影响,存储在一个独立的库中 健身函数的参数值及其算法本身在编译时由独立的裁判员设定,任何人都不能再改变。

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。

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:

为什么不是正确的呢?

哪些是缺失的?

这不仅仅是为了让参与者的生活尽可能的困难,我就是这样做的,这不是我第一天想到的,甚至不是第二天。

在你的例子中,搜索的任务被部分地委托给了检查器脚本。这是不正确的。检查器脚本应该调用搜索并检查其结果,而不是其他。

并非所有的FF参数都可用。例如,如何获得参数步长(值为0.1),可能的最大值和最小值?当然,这很好,每个用户都应该读一读这个论坛,明白步长原来是0.1,最小是-10.0,最大是+10.0,然后在他的代码中输入这些常数,希望FF函数也这样想。但这并不是一个好的方法。

许多导出函数如ServiceFunc1只用于特定的搜索算法。例如,它们不应该被用于随机搜索。那么,为什么用户库要导出它们呢?只要把测试任务和搜索任务分开,就足以意识到所有这些复杂的出口功能组合是不必要的。

还有很多事情使附加组件成为不必要的。

 
Andrey Dik:
你到底更喜欢什么?
而巴西尔的例子是第二种类型的连接,而第一种类型的连接在哪里?
你不需要第二个、第三个、110个连接类型。你只需要一个,但要有一个通用的连接类型。不使用不必要的句法结构。没有人愿意为ServiceFunc1函数的缩写含义而困惑。相反,人们应该给出一个健身函数和填充其参数的规则。而没有别的。