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

 

Реально случайное число в диапазоне 0 - 4294967295.

Генерируется побитно на основе счетчика тактов процессора. Работает и на Intel и на AMD, в том числе на новых поколениях.

#pragma warning (disable:4700) // disable - warning C4700: local variable '' used without having been initialized
DWORD realrand()
{
DWORD dwRND, dwRDTSC, dwBitCount =32;
        
        // serialization for new processors
        __asm
        {
                xor eax, eax
                cpuid                   
        }
//................................
        while(dwBitCount--)
        {
                while(dwRDTSC & 0x1FFFF) // random delay
                        dwRDTSC--;
                
                __asm
                {
                        rdtsc                           // cpu counter as random generator
                        mov dwRDTSC, eax
                }
                
                dwRDTSC >>= 1;                  // 2-ой разряд рабочий
                dwRND <<= 1;                    
                dwRND |=(dwRDTSC & 1);  // take least bit and add to random result
        }
        
return(dwRND);
}
#pragma warning (default:4700) // restore default warning

Компилировать в Microsoft Visual Studio. Как уложить результат в заданный диапазон уже написали


realrand() % 99 + 1
 

Привет!


Вообще случайное число можно самим сделать. Без встроенных функций.

 
Maxim Romanov:

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

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

это типа, раз уж рынок рандом, то добавим еще и в код рандом, на выходе должна получиться стабильность )

 

ГПСЧ на основе алгоритма Кнута. Сделан в виде класса. Из плюшек поддерживает случайной число в заданном диапазоне, например {0, 1} или {100..500}:

///
/// Генератор детерминированых псевдослучайных чисел (ГПСЧ).
///
class Random
{
   public:
      Random()
      {              
         InitValues(RANDOM_KNUTH);
      }
      
      void Seed(ulong seed)
      {
         prevValue = seed;
      }
      ///
      /// Возвращает ulong псевдослучайное число.
      ///
      ulong Rand()
      {
         ulong value = (ulong)((a*prevValue+c)%m);
         prevValue = value;
         return value;
      }
      ///
      /// Генерирует случайное число от min до max-1 включительно.
      ///
      ulong Rand(ulong min, ulong max)
      {
         ulong delta = max - min;
         if(delta <= 0)return min;
         ulong value = Rand();
         ulong m_value = value%delta;
         m_value += min;
         return m_value;
      }
   private:
      enum ENUM_RANDOM_TYPE
      {
         RANDOM_KNUTH,
         RANDOM_NEWLIB,
         RANDOM_RECIPES,
         RANDOM_BORLAND,
         RANDOM_ANSI_C,
         RANDOM_VBASIC
      };
      void InitValues(ENUM_RANDOM_TYPE type)
      {
         prevValue = 0;
         switch(type)
         {
            case RANDOM_KNUTH:
               m = ULONG_MAX;
               a = 6364136223846793005;
               c = 1442695040888963407;
               break;
            case RANDOM_NEWLIB:
               m = ULONG_MAX;
               a = 6364136223846793005;
               c = 1;
               break;
            //(Период генератора 2 147 483 648 шага (2^31 бит))
            case RANDOM_ANSI_C:
               m = 2147483648; //(2^31)
               a = 1103515245;
               c = 12345;
               break;
            case RANDOM_BORLAND:
               m = UINT_MAX;
               a = 22695477;
               c = 1;
               break;
            case RANDOM_RECIPES:
               m = UINT_MAX; //(Период генератора 65 536 шага)
               a = 1664525;
               c = 1013904223;
               break;
            case RANDOM_VBASIC:
               m = 16777216; // (2^24)
               a = 1140671485;
               c = 12820163;
               break;
         }
      }
      ulong m;
      ulong a;
      ulong c;
      ulong prevValue;
};
 
Fast528:

это типа, раз уж рынок рандом, то добавим еще и в код рандом, на выходе должна получиться стабильность )

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

 

В общем для себя я нашел более простой и подходящий способ, тем более я пока сам не знаю свой диапазон и он будет меняться.

if (Rand >= 1 && Rand <= 15000)
if (Rand >= 15001 && Rand <= 30000)

Скажем этот пример для двух параметров. Только вот со switch это не катит.

 
Aleksey Rodionov:

В общем для себя я нашел более простой и подходящий способ, тем более я пока сам не знаю свой диапазон и он будет меняться.

Скажем этот пример для двух параметров. Только вот со switch это не катит.

Чот толсто)) Начали с проблемы получения случайных чисел закончили тривиальными операторами ветвления.

Switch проверяет на строгое равенство аргумента целочисленного типа заданным константам (C++/MQL). Для проверки неравенств есть if, а если условия взаимоисключающие else if

Rand =(Rand % 30000 + 1); // на выходе всегда будет число в диапазоне 1 - 30000

if(Rand > 15000) // тут будут 15001 - 30000
{
}
else // тут будут 1 - 15000
{
}

// если диапазонов несколько используем else if
if(Rand > 22500) // 22501 - 30000
{
}
else
if(Rand > 15000) // 15001 - 22500
{
}
else
if(Rand > 7500) // 7501 - 15000
{
}
// ... и т.д.
else // 1 - 7500
{
}
 
SemenTalonov:

Чот толсто)) Начали с проблемы получения случайных чисел закончили тривиальными операторами ветвления.


У меня и получится случайное, просто пока не знаю диапазон, думаю разбег будет: 1-100  101-200  201-300 и т.д.

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

 
Aleksey Rodionov:

У меня и получится случайное, просто пока не знаю диапазон, думаю разбег будет: 1-100  101-200  201-300 и т.д.

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

int n = rand()%10*100;
int cnt = rand()%99+1+n;
Все довольно просто. Так-же рандомно выбирается диапазон.
 
Смотрю многие делают одну и ту же ошибку: используют оператор взятия остатка %.  Такое допустимо лишь в том случае, когда исходный диапазон случайных чисел кратен делителю.  Т.е. нашем случае такими делителями являются двойки в различных степенях:  2, 4, 8 и т.д.  Так вот только для них можно писать такое:  rand()%8.
Для любых других делителей вы получите перекос вероятности. Поэтому там нужно делать через вычисление вещественного остатка:  floor(fmod(rand(), 100)) - получаем число от 0 до 99
Причина обращения: