согласованность семян srand между физическими машинами

Я не совсем уверен, как сформулировать этот вопрос, но я не смог найти ничего подобного.

Скажем, у меня есть этот код:

srand(1);
srand(SOME_DEFINED_CONST_INT);

Если я запускаю этот исполняемый файл на нескольких разных физических машинах, гарантируется ли согласованность последовательности rand() между ними? то есть, если я получу 1, 4, 6, 3, 4 на одной машине, всегда ли я получу ту же последовательность на других?

Если да, как это можно доказать? Это часть стандарта?

Если нет, могу ли я что-нибудь сделать, чтобы это было так?


person badgerr    schedule 09.03.2011    source источник


Ответы (4)


Нет, стандарт ничего подобного не гарантирует. Однако логика генерации случайных чисел находится внутри стандартной библиотеки C. Поэтому, если вы создаете приложение с той же версией библиотеки, последовательность должна быть такой же. Вторая часть моего ответа — всего лишь предположение, но стандарт точно не дает никаких гарантий.

person Armen Tsirunyan    schedule 09.03.2011

Как сказал Армен, это нестандартно. Однако, если вы посмотрите на справочную страницу для srand() в Linux, вы увидите кое-что интересное:

POSIX 1003.1-2003 дает следующий пример реализации rand() и srand(), который может быть полезен, когда нужна одна и та же последовательность на двух разных машинах.

       static unsigned long next = 1;

       /* RAND_MAX assumed to be 32767 */
       int myrand(void) {
           next = next * 1103515245 + 12345;
           return((unsigned)(next/65536) % 32768);
       }

       void mysrand(unsigned seed) {
           next = seed;
       }
person Mat    schedule 09.03.2011
comment
Эта реализация никогда не должна использоваться. Это в принципе плохо. Если вам нужна согласованная генерация случайных чисел между машинами, обратите внимание на современные методы. Отправной точкой является Mersenne Twister, более современные алгоритмы можно найти в Numerical Recipes версия 3. - person Alexandre C.; 09.03.2011
comment
В качестве альтернативы, если вам не нужно напыщенное качество MT (которое часто является излишним), вы можете рассмотреть генераторы xor-shift от Marsaglia. У них 2 ^ 32-1 периода в 32 битах и ​​2 ^ 64-1 периода в 64 битах, чего обычно достаточно (во всяком случае, для меня). Они производят качественные псевдослучайные числа (проходя несгибаемые), смехотворно просты в реализации и смехотворно быстры. Единственное предостережение заключается в том, что они генерируют последовательность нулей, если засеяны нулем (интересно, почему Марсалья этого не оценил?), но это можно легко преодолеть, добавив ненулевую константу перед выполнением сдвигов и исключающих операций. - person Damon; 09.03.2011
comment
Уточнение: я не говорил, что srand не является стандартным! Это! Это поведение не :) - person Armen Tsirunyan; 09.03.2011

Как сказал Мэт, всегда полезно реализовать генератор случайных чисел самостоятельно. Желательно объектно-ориентированным способом. В качестве приятного побочного эффекта вы можете получить безопасность потоков и, возможно, скорость помимо согласованности на разных платформах. Линейные конгруэнтные генераторы http://en.wikipedia.org/wiki/Linear_congruential_generator или скручивание Мерсенна http://en.wikipedia.org/wiki/Mersenne_twister поможет вам в этом.

person Jonas Bötel    schedule 09.03.2011
comment
LCG плохи для многих приложений. Твистер Мерсенна сложен и начинает устаревать. - person Alexandre C.; 09.03.2011

Я добавлю, что если вы работаете под Windows, если вы берете свой exe и перемещаетесь между машинами, srand БУДЕТ генерировать те же числа, потому что реализация srand зависит от разработчика, но вы всегда будете использовать время выполнения один и тот же разработчик (поэтому, если вы используете Microsoft C++, вы будете использовать srand Microsoft, и MS, вероятно, не изменит свою реализацию srand ни сегодня, ни завтра). То же самое для линукса. Ваш srand всегда будет glibc. Если они не изменят его в glibc, цифры останутся прежними.

person xanatos    schedule 09.03.2011