Всегда ли stdlib rand () дает одинаковую последовательность? - PullRequest
6 голосов
/ 17 августа 2010

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

Гарантируется ли это при повторных выполнениях на одной и той же машине / для разных машин / для разных архитектур?

* Для того же семени очевидно.

Ответы [ 6 ]

20 голосов
/ 17 августа 2010

Да, учитывая ту же среду для программы.Из стандарта C § 7.20.2.2 / 2,

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

Конечно, это предполагает, что он использует ту же деталь реализации (т. е. тот же компьютер, та же библиотека при том же выполнениипериод).Стандарт C не требует стандартного алгоритма генерации случайных чисел, поэтому, если вы запускаете программу с другой стандартной библиотекой C, можно получить другую последовательность случайных чисел.

См. Вопрос Согласованные псевдослучайные числа на разных платформах , если вам нужна переносимая и гарантированная последовательность случайных чисел с заданным начальным числом.

2 голосов
/ 18 августа 2010

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

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

Если вы хотите большего детерминизма, вам следует внедрить PRNG с конкретными параметрами в вашей программе.

1 голос
/ 17 августа 2010

номер

Стандарт C гласит:

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

Но нигде не говорится, какова последовательность псевдослучайных чисел на самом деле - так что она отличается в разных реализациях.

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

0 голосов
/ 15 ноября 2010

Если вы находитесь в среде UNIX / Linux, вы можете увидеть drand48 () и srand48 () на своих страницах руководства, если вы не можете, вы можете увидеть онлайнруководства для языка Си.Прототипы можно найти по адресу / usr / include / stdlib.h .Первый использует линейный конгруэнтный метод, который часто используется в симуляциях.

Если вы предоставите srand48 () то же самое начальное число, то есть srand48 (2), а затем поместите dran48 () в цикл for, последовательность будет одинаковой каждый раз.т.е.

include stdio.h
include stdlib.h
double drand48();
int main(void){
    int i;
    double rn;
    srand48(2);
    for(i=0; i<10; i++){
        randNum = drand48();
        printf("%.6l\n", randNum);
        return 0;
}
0 голосов
/ 17 августа 2010

При переключении на другую машину / время выполнения / все, что вам может не повезло.Существует еще один возможный выбор семейства функций drand48.Они нормализованы для использования одного и того же алгоритма на всех машинах.

0 голосов
/ 17 августа 2010

Если вам нужно использовать точно такой же набор псевдослучайных чисел для экспериментальных целей, вы могли бы использовать srand для генерации длинной последовательности случайных чисел и записи их в файл / базу данных. Затем напишите переносимую функцию «генератора случайных чисел», которая последовательно возвращает значения из этого файла. Таким образом, вы можете быть уверены, что используете одни и те же входные данные независимо от платформы, srand реализации или начального значения.

...