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

 

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

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

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

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

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

 
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);
}
Далее - "растягиваем" полученное значение на нужный диапазон (умножая на ширину диапазона, и прибавляя точку минимума диапазона, получаем равномерное распределение в диапазоне), а если необходимо нормальное распределение - преобразуем его по известным формулам (с помощью преобразования Бокса-Мюллера).
 
Aleksey Rodionov:

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

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

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

 
rand()%99+1
 
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)));
}


 

 

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

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

 
Aleksey Rodionov:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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