Как лучше всего использовать srand ()?

Я научился сначала засеивать генератор случайных чисел srand(time(NULL)), а затем использовать вызовы rand() для генерации случайных чисел. Проблема с этим подходом в том, что если я запускаю свою программу несколько раз за одну секунду, сгенерированные случайные числа всегда будут одинаковыми. Что можно сделать в этом направлении?


person Matt    schedule 06.04.2013    source источник
comment
Вы можете прибегнуть к системному методу для большей точности. Например, в Windows есть GetTickCount. * nix имеет clock_gettime.   -  person chris    schedule 06.04.2013
comment
В заголовке и в теле вопроса задаются две разные вещи.   -  person Pubby    schedule 06.04.2013
comment
Не запускайте программу быстро? Получите таймер с большей точностью?   -  person Jeff Mercado    schedule 06.04.2013
comment
Что ж, вы можете смешивать множество источников информации для использования в качестве случайного числа. stime(time(NULL) * getpid()), например, это поможет.   -  person Havenard    schedule 06.04.2013
comment
@Havenard. Умножение - лучший способ их совместить? Будет ли работать и xor?   -  person Matt    schedule 06.04.2013
comment
XOR будет довольно плохим, потому что pid обычно увеличивается на 1 при каждом запуске, а если время также увеличивается на 1, вы можете легко получить тот же результат.   -  person R.. GitHub STOP HELPING ICE    schedule 06.04.2013
comment
Думаю, на самом деле это не имеет значения.   -  person Havenard    schedule 06.04.2013


Ответы (5)


В системах POSIX используйте clock_gettime, чтобы получить текущее время в наносекундах. Если вам не нужно много битов, вы можете просто забыть о ГПСЧ и напрямую использовать младшие биты времени в качестве случайного числа. :-)

person R.. GitHub STOP HELPING ICE    schedule 06.04.2013
comment
Я предполагаю, что кому-то не понравилась моя идея использовать младшие биты текущего времени для ГСЧ. Однако, учитывая факторы, которые на них влияют (задержка памяти, попадания / промахи в кеше, промахи TLB, подкачка, время прерывания, планирование и т. Д.), А также тот факт, что наносекунды примерно соответствуют циклам на современных машинах, они чертовски хороши. хороший источник энтропии. - person R.. GitHub STOP HELPING ICE; 12.04.2013
comment
Я согласен. Это одновременно умно и элегантно. Отсюда мой вопрос. Я был озадачен отрицательным голосом за такой подходящий ответ на рассматриваемый вопрос. Это в значительной степени решает вопрос (запуск программы несколько раз за одну секунду и получение каждый раз одного и того же результата). - person Jean; 12.04.2013

int pid ; // get it as per your OS
timeval t;
gettimeofday(&t, NULL);
srand(t.tv_usec * t.tv_sec * pid);

time дает вам значения, основанные на second. gettimeofday основан на microseconds. Так что меньше шансов на то, что произойдет то же самое семя. Кроме того, вы также используете идентификатор процесса.

person user93353    schedule 06.04.2013

Если * nix, почему не читаете прямо с /dev/random?

Также вы можете собирать шум от других устройств, таких как клавиатура, мышь или температура процессора.

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

Я считаю, что Glib предоставляет функцию g_random_int(), которая производит случайные числа, равномерно распределенные, быстрым и переносимым способом.

Или вы можете просто прочитать количество временных файлов в /tmp и использовать это количество для подачи srand() функцией time.h или прочитать содержимое одного файла в /tmp.

Вы можете прочитать каждый файл из /usr/bin или / и собрать немного еды для srand().

person yeyo    schedule 06.04.2013
comment
Мистер -1, я с нетерпением жду возможности прочитать причины. - person yeyo; 06.04.2013

Помимо использования времени, еще один распространенный способ засеять вашу функцию rand - использовать идентификатор процесса вашей программы, поскольку он гарантированно уникален.

Фактический код зависит от платформы, но если вы работаете в Windows, я считаю, что вы можете использовать функцию GetCurrentProcessId(), как в

srand(GetCurrentProcessId());
person Parker Kemp    schedule 06.04.2013
comment
Таким образом, вы будете получать одну и ту же последовательность случайных чисел каждый раз, когда вызываете функцию rand. - person prehistoricpenguin; 06.04.2013
comment
@prehistoricpenguin Что ты имеешь в виду? - person Matt; 06.04.2013
comment
@prehistoricpenguin, только если у вашего процесса каждый раз один и тот же PID. Вот почему это хорошая идея смешать его с функцией времени. - person chris; 06.04.2013

Помимо ввода времени, вы можете добавить к нему время процессора, что, как я считаю, можно сделать с помощью clock (). Это будет выглядеть так: srand(time() + clock()).

person fibonatic    schedule 06.04.2013