Подтвердить что ты не робот

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));
4b9b3361

Ответ 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, выходите из программы и запускаете очень быстро, цифры будут одинаковыми)