Как получить случайное число в N-ном деапазоне ?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Aleksey Rodionov
5379
Aleksey Rodionov  

Как можно получить случайное число в диапазоне, пример: от 1 до 100 ?

Функцию MathRand() не рассматриваю т.к. провел пол дня в поисковике, пришел к выводу данный метод не подходит из-за того что все равно из-за формул не совсем корректно получается генерация цифр от 1 до 100

Например такая формула

double RNDfromCI(double min,double max)
{return(min+((max-min)*MathRand()/32767.5));}

Может есть еще варианты без данной функции ?

Georgiy Merts
9181
Georgiy Merts  
Aleksey Rodionov:

Как можно получить случайное число в диапазоне, пример: от 1 до 100 ?

Функцию MathRand() не рассматриваю т.к. провел пол дня в поисковике, пришел к выводу данный метод не подходит из-за того что все равно из-за формул не совсем корректно получается генерация цифр от 1 до 100

Например такая формула

Может есть еще варианты без данной функции ?

Я еще со времен калькуляторов использовал формулу X = { X * 11 + Pi }  (фигурные скобки - получение дробной части).

То есть, текущее число от нуля до единицы сдвигается на один десятичный разряд, и прибавляется к самому себе. После чего к нему добавляется еще и число пи, и от этого всего берется дробная часть.

Проверка на равномерность распределения показывает, что это хороший равномерный генератор случайных чисел. 

Сейчас я использую эту формулу несколько "расширенно", используя добавочно стандартный генератор случайных чисел и системный таймер (в составе класса CRandomizator, основное значение - m_dRandom, это член класса, оно должно храниться, от него и получаем следующее псевдослучайное значение) :

#define RAND_FRAC_FACTOR 65536

double CRandomizator::GenerateStandartUniDistRandom()
{
   uint   uiRand = GetTickCount() % RAND_FRAC_FACTOR; // uiRand = 0 ~ RAND_FRAC_FACTOR-1
   double dRand = MathRand();                         // dRand = 0 ~ 32767
   
   dRand += uiRand;                                   // dRand = 0 ~ (RAND_FRAC_FACTOR + 32766)
   
   dRand /= RAND_FRAC_FACTOR;                         // dRand = 0 ~ (1 + 32766/RAND_FRAC_FACTOR)
   
   dRand += ((m_dRandom * 11) + M_PI);                // dRand = Pi ~ (12 + Pi + 32766/RAND_FRAC_FACTOR)
   
   m_dRandom = dRand - MathFloor(dRand);              // m_dRandom = [0..1)
   
   return(m_dRandom);
}
Далее - "растягиваем" полученное значение на нужный диапазон (умножая на ширину диапазона, и прибавляя точку минимума диапазона, получаем равномерное распределение в диапазоне), а если необходимо нормальное распределение - преобразуем его по известным формулам (с помощью преобразования Бокса-Мюллера).
Petros Shatakhtsyan
14394
Petros Shatakhtsyan  
Aleksey Rodionov:

Как можно получить случайное число в диапазоне, пример: от 1 до 100 ?

Функцию MathRand() не рассматриваю т.к. провел пол дня в поисковике, пришел к выводу данный метод не подходит из-за того что все равно из-за формул не совсем корректно получается генерация цифр от 1 до 100

А в чем некорректность ?

Konstantin Nikitin
8594
Konstantin Nikitin  
rand()%99+1
Andrey Dik
13682
Andrey Dik  
Aleksey Rodionov:

Как можно получить случайное число в диапазоне, пример: от 1 до 100 ?

Функцию MathRand() не рассматриваю т.к. провел пол дня в поисковике, пришел к выводу данный метод не подходит из-за того что все равно из-за формул не совсем корректно получается генерация цифр от 1 до 100

Например такая формула

Может есть еще варианты без данной функции ?

Здравствуйте.

В чем некорректность работы этой функции? - поясните, пожалуйста.

Похоже, это моя функция, применяемая в ранних версиях ГА. Сейчас использую с проверкой на корректность min и max:

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)));
}

можно чуть изящнее:

double RNDfromCI(double min, double max) 
{
  if(min == max) 
    return (min);
  double Min = fmin (min, max);
  double Max = fmax (min, max);
  return (double(Min + ((Max - Min) * (double)MathRand() / 32767.0)));
}


 

Aleksey Rodionov
5379
Aleksey Rodionov  

По поводу корректности. Просто когда читал много тем именно с генерациями чисел на форуме  mql5, как бы попроще объяснить...

Например мне нужно случайное значение от 1 до 250,  если при расчет формулы деления, вычитания и т.д. от 32767 то например если функция MathRand() будет выдавать значение от 15000 до 17000 то окончательное значение будет ровное, скажем 135.

Andrey Dik
13682
Andrey Dik  
Aleksey Rodionov:

По поводу корректности. Просто когда читал много тем именно с генерациями чисел на форуме  mql5, как бы попроще объяснить...

Например мне нужно случайное значение от 1 до 250,  если при расчет формулы деления, вычитания и т.д. от 32767 то например если функция MathRand() будет выдавать значение от 15000 до 17000 то окончательное значение будет ровное, скажем 135.

Не парьтесь над этим. разрешающей способности MathRand хватает для подавляющего большинства практических задач.

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

Fast235
2002
Fast235  
в чем их обычно используют? пытаюсь придумать что-нибудь полезное, ничего не идет пока
Nikolay Khrushchev
21423
Nikolay Khrushchev  
Fast528:
в чем их обычно используют? пытаюсь придумать что-нибудь полезное, ничего не идет пока

99% стратегий на индикаторах не отличаются от if(MathRand()<16384) OpenBuy(); else OpenSell(); 

некоторые любители мартышек не заморачиваются над сигналом и просят похожую конструкцию )
Maxim Romanov
7419
Maxim Romanov  
Nikolay Khrushchev:

99% стратегий на индикаторах не отличаются от if(MathRand()<16384) OpenBuy(); else OpenSell(); 

некоторые любители мартышек не заморачиваются над сигналом и просят похожую конструкцию )

Да, я когда мартышками занимался, тоже применял случайный вход. Потом сделал проще, заменил случайный на анализ предыдущей свечи, если растущая, то... покупать/продавать на свой вкус.

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

Stanislav Aksenov
28096
Stanislav Aksenov  
Fast528:
в чем их обычно используют? пытаюсь придумать что-нибудь полезное, ничего не идет пока
Nikolay Khrushchev:

99% стратегий на индикаторах не отличаются от if(MathRand()<16384) OpenBuy(); else OpenSell(); 

некоторые любители мартышек не заморачиваются над сигналом и просят похожую конструкцию )

В реальной жизни профессиональные программисты (c++, c#, java etc.) в своих задачах очень часто применяют рандом. ну очень часто.

И вообще, я вам скажу, что сама природа тоже.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий