Srand (time (NULL)) не меняет начальное значение достаточно быстро
Я написал простой генератор случайных чисел в C. int l
- нижняя граница, а int u
- верхняя граница.
Это работает отлично, однако у меня есть вопрос относительно его посева. Если бы я запускал это в цикле, time(NULL)
не меняет начальное значение достаточно быстро, чтобы избежать возможности последовательной серии случайных чисел, которые являются точно такими же.
Мне интересно, как кто-то другой мог подойти к этой проблеме. Все примеры, которые я нашел в Интернете, используют time(NULL)
в качестве генератора исходных значений.
int generateRandom(int l, int u)
{
srand(time(NULL));
int r = rand() % ((u - l) + 1);
r = l + r;
return r;
}
Если бы я должен был запускать эти строки кода рядом друг с другом, то оба Rand1
и Rand2
были бы точно такими же.
printf("Rand1 = %d\n", generateRandom(10, 46));
printf("Rand2 = %d\n", generateRandom(10, 46));
Ответы
Ответ 1
srand(time(NULL))
должен выполняться ровно один раз для инициализации PRNG. Сделайте это в главном при запуске приложения.
Объяснение:
PRNG (Генератор псевдослучайных чисел) генерирует детерминированную последовательность чисел, зависящую от используемого алгоритма. Данный алгоритм всегда будет производить одну и ту же последовательность из заданной начальной точки (семени). Если вы явно не высеиваете PRNG, он обычно запускается из одного и того же семени по умолчанию каждый раз, когда приложение запускается, в результате получается одна и та же последовательность чисел.
Чтобы исправить это, вам нужно засеять PRNG самим другим семенем (чтобы дать другую последовательность) каждый раз, когда приложение запускается. Обычный подход заключается в использовании time(NULL)
, который устанавливает семя на основе текущего времени. Пока вы не запускаете два экземпляра приложения в течение секунды друг от друга, вам гарантируется другая случайная последовательность.
Нет необходимости высевать последовательность каждый раз, когда вы хотите получить новое случайное число. И я не уверен в этом, но у меня есть ощущение, что в зависимости от используемого алгоритма PRNG повторное посев для каждого нового номера может фактически привести к более низкой случайности в полученной последовательности.
Ответ 2
Семя один раз в начале основного. Если вы повторно загрузитесь слишком быстро в течение одной секунды, вы получите одинаковые номера.
Ответ 3
Не выкладывайте его каждый раз, только в начале вашей программы.
Кроме того, многие книги советуют использовать стандартные случайные функции C-lib. Если вам нужны хорошие псевдослучайные числа, есть хороший алгоритм в Press et al., Numerical Recipes, 3rd. Выпуск.
Ответ 4
Я предполагаю, что вы вызываете функцию generateRandom
из другой функции, main
или что-то еще.
Если вы объявите семя внутри функции, вы будете reset функцией. Сброс функции приведет к тому, что одни и те же цифры появятся несколько раз, в ту же секунду.
Перемещение srand(time(NULL));
на главную функцию решит проблему.
Ответ 5
srand( (unsigned) time(NULL) * getpid());
дает более разнообразный случайный набор (на OSX 10.8), в том числе на тестах с коротким циклом.
Ответ 6
Если вы используете разные процессы, используйте (rand()+getpid())%range;
Я использую его для тестирования одной и той же программы со случайными значениями много раз в секунду (если вы делаете номера rand, выходите из программы и запускаете очень быстро, цифры будут одинаковыми)