2013-07-28 2 views
0

Есть ли способ использовать стандартную библиотеку C++, построенную в случайном генераторе, чтобы получить определенное случайное число в последовательности, не сохраняя их все?Получить случайное число в последовательности C++

Как

srand(cTime); 
getRand(1); // 10 
getRand(2); // 8995 
getRand(3); // 65464456 
getRand(1); // 10 
getRand(2); // 8995 
getRand(1); // 10 
getRand(3); // 65464456 
+0

С помощью tweak вы можете генерировать случайные числа в определенном диапазоне, например, если вам нужны случайные числа только с 0-36, тогда вы можете легко достичь этого, используя оператор% (например, rand()% 36) с rand() но я не знаю никакой встроенной функции, которая будет принимать X в качестве входного сигнала для getRand (X) и генерировать что-то f (X) каждый раз. – Saby

ответ

1

C++ 11 случайное число двигатели должны реализовать функцию-член discard(unsigned long long z) (§26.5.1.4), которая продвигает последовательность случайных чисел на z шагов. Гарантия сложности довольно слабая: «не хуже сложность z последовательных звонков e()». Этот элемент, очевидно, существует исключительно, чтобы сделать возможным подвергать более производительным реализации, если это возможно, как примечание 274 состояния:

Эта операция обычно используется в коде пользователя, и часто могут быть реализованы в манере двигателя конкретного так, чтобы обеспечивают значительную производительность улучшений над эквивалентным наивным циклом, который составляет z последовательных звонков e().

Учитывая discard вы можете легко реализовать ваши требования для извлечения n-го числа в последовательности, пересев генератора, отбрасывая n-1 значения и используя следующее сгенерированное значение.

Я не знаю, какие из стандартных двигателей RNG могут быть применены к эффективным реализациям discard. Возможно, стоит потратить немного времени на изучение и профилирование.

0

Вы должны сохранить номера. Могут быть и другие варианты, но по-прежнему требуется сохранить список чисел (например, используя разные семена на основе аргумента getRand()), но это не выгодно для их сохранения).

Что-то, как это будет работать достаточно хорошо, я бы сказал:

int getRand(int n) 
{ 
    static std::map<int, int> mrand; 
    // Check if it's there. 
    if ((std::map::iterator it = mrand.find(n)) != mrand.end()) 
    { 
     return it->second; 
    } 

    int r = rand(); 
    mrand[n] = r; 
    return r; 
} 

(я не компилируется этот код, только что написал его в качестве «такого рода вещи могли бы работать»)

+0

Сохранение - это не вариант, могут быть миллионы чисел в зависимости от того, как долго работает приложение. –

+0

Ну, вы не можете получить тот же номер дважды, не сохраняя ни числа, ни используя новое (но одно и то же) семя каждый раз. Обратите внимание, что экономия миллионов чисел не должна быть проблемой на современном компьютере - даже мобильный телефон имеет много мегабайт памяти в наши дни. 1M numbers = ~ 4MB (хотя «карта», возможно, займет немного больше места). Весь смысл «rand» в том, что он генерирует другое число каждый раз, когда вы его вызываете. Конечно, вы можете называть 'srand' новым семенем каждый раз, но это потребует сохранения и создания хороших семян для каждого порядкового номера, так что это еще хуже. –

+0

Как вы это достигаете в Java? –

0

Внесите getRand(), чтобы всегда посеять, а затем вернуть заданное число. Это будет мешать всем другим случайным числам в системе, хотя и будет медленным, особенно для больших индексов. Предполагая, что индекс в 1 на основе:

int getRand(int index) 
{ 
    srand(999); // fix the seed 
    for (int loop=1; loop<index; ++loop) 
     rand(); 
    return rand(); 
} 
+0

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

0

Подобный пост cdmh, в

Исходя из C++ 11 также могут быть использованы:

#include<random> 

long getrand(int index) 
{ 
std::default_random_engine e; 
for(auto i=1;i<index;i++) 
    e(); 
    return e(); 
} 
0

Отъезд: Random123

Из документации:

Random123 представляет собой библиотеку «счетчика на основе» генераторов случайных чисел (CBRNGs), в которой N-й случайное число может быть получено путем применения функции лица без перемешивания до N ..

Смежные вопросы