Функция srand в C++

код

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main ()
{
    printf ("First number: %dn", rand() % 100);
    srand ( time(NULL) );
    printf ("Random number: %dn", rand() % 100);
    srand ( 1 );
    printf ("Again the first number: %dn", rand() %100);

    return 0;
}

имеет следующий результат:

First number: 41
Random number: 13
Again the first number: 41

существует также следующее правило:

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

Я понимаю слова, но я просто не понимаю сам метод. Почему он снова вернулся 41? Это случайно или должно вернуться? один и тот же результат в каждом случае согласно этому кодексу?

6 ответов


если вы называете rand() без предварительного вызова srand(), поведение такое, как будто вы вызвали srand() С 1 в качестве аргумента.

это поведение определено в исходном стандарте C. У меня нет полной копии, но стандарты POSIX открытой группы-это следующая лучшая вещь, поскольку они включают полный стандарт C (с некоторыми расширениями):

http://www.opengroup.org/onlinepubs/000095399/functions/rand.html

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

фактический результат rand() вызов для любого заданного семян реализация-определена, за исключением того, что для любого семени x, называют n to rand() после посева генератора необходимо вернуть тот же результат. Таким образом, в то время как на вашей реализации вы всегда получите 41 на первом rand() звонок после вызова srand(1), и вы всегда получите тот же результат (что бы это ни было) для второго rand() звонок, другие реализации могут использовать другой алгоритм, который дает разные результаты.


стандарт C++ переносится на стандарт C для rand и srand (см. раздел 26.8 C++0x):

на rand функция имеет семантику, указанную в стандарте C, за исключением того, что реализация может указать, что определенные библиотечные функции могут вызывать rand.

стандарт C (7.20.2.2 C99) гласит довольно категорично:

если rand вызывается перед вызовом srand были сделаны, то же самое последовательность генерируется как когда srand сначала вызывается с начальным значением 1.

в первый раз вы называете rand, семя-1. Это также 1 в третий раз, когда вы называете его, поэтому вы получаете то же значение.

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


Я думаю, что это может быть проблема:

Если seed имеет значение 1, генератор повторно инициализируется до своего начального значения и выдает те же значения, что и до любого вызова rand или srand.

srand reference


вызов srand стоимостью 1 сбрасывает генератор в исходное состояние при запуске программы.


srand(3) позволяет получить повторяемый выход из генератора случайных чисел. Таким образом, вы можете писать программы, зависящие от случайных чисел, но тестировать их детерминированно. (Как правило, с помощью опции командной строки для вызова srand() с предоставленным аргументом, поэтому его можно запустить сто раз с помощью 1, 2, 3, 4, 5, ... в качестве входов.)

Так это правильно.


Это, вероятно, потому, что в вашем первоначальном вызове rand генератор случайных чисел не был посеян, поэтому он использует значение по умолчанию 1 для его посева.