算法优化锦标赛。 - 页 52

 

为什么要在第二个例子中导入

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

好吧,我也可以这么写--我的问题有什么不清楚的地方?

这更像是一个反问,因为我相信你能理解。

德米特里-费多塞耶夫
为什么一个问题我得问10次?

这是一个困难的问题,我也经常想这个问题)。

德米特里-费多塞耶夫

为什么在第二个例子中需要导入?

为了从脚本中控制算法,该算法实际调用了多少次FF。

对于第一种变体,它是明显可见的,因为脚本本身就会进行调用,但对于第二种变体,它是不可见的,这就是为什么我们需要从脚本中访问FF库的能力。

 

现在,我想对所有参与者说,他们认为自己是这一主题的 "新人",并不认真期待获胜

如果我们放弃所有关于空间多维度的疯狂 "理论",它使问题变得如此混乱,并转向纯数学,我们看到FF是一个方程式

这个方程只有 在应用于图形时才 会成为一个分析函数。

但有一个问题--是否 应该这样做? 图形只是帮助可视化方程参数之间的关系。

经过158页的讨论,我们已经可以提出问题的本质。

我们需要找到方程右边的变量的值,在这个值上,方程左边的变量的值 是最大的。

我们的目标是尝试比完全的蛮力更有效地做到这一点。

就这样了。

下一步。

为了解决这个问题,人们发明了一种寻找数值的 "进化 "技术。源自达尔文主义的类比和方法被构建出来。

这种方法的效率问题是值得商榷的。也许,有更简单、更有效的方法来解决这个问题。

我的实践证明,普遍接受的方法并不总是最有效的。

我相信我们可以很好地绕过 "进化论者"...

让我们试一试吧!

 

参与者对调用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)));
}
//————————————————————————————————————————————————————————————————————

算法的基本代码与第一种变体相同,但从算法中调用FF,而不是从脚本中调用。

其结果自然与第一种变体相似。

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

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

2016.06.22 11:47:45.321 OAC variant 2 (GBPUSD,M30) FF Runs: 1000

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

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

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

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

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

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

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

2016.06.22 11:47:37.309 OAC variant 2 (GBPUSD,M30) FF Runs: 1000

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

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

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

2016.06.22 11:47:32.933 OAC variant 2 (GBPUSD,M30) FF Runs: 1000

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

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

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

2016.06.22 11:47:07.584 OAC variant 2 (GBPUSD,M30) FF运行: 1000

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

那就是--一点也不差。

 

所以,上面的例子显示了参与者的算法通过导入函数 与测试脚本的连接方式。

让我提醒你,为什么要组织这样的方式来处理参赛者的算法:一方面要隐藏参赛者的算法以保护知识产权,另一方面要让评委和观众都能控制和验证。

 

我今天会测试一下。

但是,最好是在一个帖子中汇编(我理解,Andrei,你很匆忙)并公布有关文件的规则,并附上这些文件的附件。不一定是现在,但要有一个起点。

 
Реter Konow:

现在,我想向所有参与者发出呼吁,他们认为自己是这一主题的 "新人",并不认真期待获胜

如果我们放弃所有关于空间多维度的疯狂 "理论",这将极大地混淆一个已经很混乱的问题,并转向纯数学,我们看到FF是一个方程式

这个方程只有 在应用于一个图形时才 会成为一个解析函数。

但有一个问题--这是否是? 图形只是帮助可视化方程参数的关系模式。

经过158页的讨论,我们已经可以提出问题的本质。

我们需要找到方程右边的变量的值,在这个值上,方程左边的变量的值 是最大的。

我们的目标是尝试比完全列举更有效地做到这一点。

就这样了。

下一步。

为了解决这个问题,人们发明了一种寻找数值的 "进化 "技术。源自达尔文主义的类比和方法被构建出来。

这种方法的效率问题是值得商榷的。也许,有更简单、更有效的方法来解决这个问题。

我的实践证明,普遍接受的方法并不总是最有效的。

我相信我们可以很好地绕过 "进化论者"...

让我们试一试吧!

如果你抛开这个帖子的情感内涵,你说的基本上是真的。你唯一忘了提到的是,在给定的锦标赛中,FF方程式本身是未知的(在生活中,它可能知道,也可能不知道)。

关于 "非虚构的理论"--我在这个主题中对优化算法的原理给出了明确的提示,这些原理在其他地方没有使用,而且以前也没有使用过(至少在现有的资料中)。而选择总是由研究人员决定的--他将如何以及在算法中使用什么。在上面的例子中,是一个与达尔文毫无关系的算法,甚至是间接的。有很多优化方法,没有人,至少我没有声称 "源于达尔文 "更好。

因此,祝愿初学者好运!继续前进,走向胜利!

 
我没有在五号机上编码过,也没有出口/进口操作的经验。请告诉我,我对你的例子的理解是否正确。我把我的评论写在了代码中。另一个问题.如果FF将由公式给出,是否会有除法或抽根操作。 零或负值将导致关键错误并停止程序
// -- данный код находится на стороне жюри (организатора)---------------------
#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:
我不在A上编码,也没有出口-进口操作的经验。请告诉我,我对你的例子的理解是否正确。我把我的评论写在了代码中。另一个问题.如果FF将由公式给出,是否会有除法或抽根操作。 零或负值将导致关键错误并停止程序

是的,你对FF冠军的运作方式的理解是正确的。

关于在参数数组大小不正确的情况下返回结果的唯一修正--参与者的算法知道FF参数的数量,如果它向FF发送了一个大小不正确的数组,那是参与者的算法问题,而不是FF的。想想这一点,如果你以市场为例--市场永远不会通知你,你在交易中使用了 "错误 "的策略参数数量,你只会得到一个负面的交易结果,仅此而已,市场不会对你的错误作出任何解释。

你可以用 "我们 "这个词代替 "你",你可以用 "我们 "代替 "你"--一切都不会改变,一切都会保持真实。

 
Igor Volodin:

我今天会测试一下。

但是,最好是在一个帖子中汇编(我理解,Andrei,你很匆忙)并公布有关文件的规则,并附上这些文件的附件。不一定是现在,但要有一个起点。

也许,把例子的文件放在一个可访问的文件存储器中会很方便,这样就不会跳着去寻找它们,并在分支的开头放置一个指向该存储器的链接。

是的,我将这样做。