Может ли rand() использоваться для генерации предсказуемых данных?
Моя цель - создать 2D или 3D-геометрию без необходимости хранить ее на диске, поэтому моя цель состоит в том, чтобы иметь какую-либо функцию, чем генерировать те же значения в соответствии с маленьким семенем. Я не хочу искать случайные значения, но если те же "случайные" данные мусора возвращаются при получении одного и того же семени, это то, что я ищу.
Если я даю srand() одно и то же целое число, я получаю одну и ту же последовательность из rand(). Это намеченная функция? Если нет, существуют ли известные стандартные функции, предназначенные для выполнения одного и того же?
Хотя я пробовал это на ideone и на моем компьютере, и у меня разные результаты, я могу понять, что эти реализации функций не описаны, поэтому это объясняет.
Ответы
Ответ 1
Если я даю srand() одно и то же целое число, я получаю одну и ту же последовательность из rand(). Это намеченная функция?
Да, см. 7.20.2.2:
7.20.2.2 Функция srand
[...] Описание
Функция srand
использует аргумент как семя для новой последовательности псевдослучайных номера, возвращаемые последующими вызовами на rand
. Если srand
вызывается с помощью одно и то же начальное значение, последовательность псевдослучайных чисел повторяется.
Однако это верно только для той же реализации srand
/rand
. Другая реализация может не использовать один и тот же алгоритм, и поэтому не будет производить одну и ту же последовательность.
Если нет, существуют ли известные стандартные функции, предназначенные для выполнения одной и той же вещи?
Ну, функции являются стандартными, но только в их поведении, а не в реальных значениях (см. примечание к реализации выше). Вам лучше использовать специальный генератор из предопределенных генераторов случайных чисел С++ 11, поскольку они стандартизованы.
Ответ 2
"Если я даю srand() одно и то же целое число, я получаю одну и ту же последовательность из Rand(). Это намеченная функция?
Да.
Если вы засеваете тот же генератор случайных чисел с тем же семенем, он даст тот же результат.
Стандартная библиотека rand и все ее варианты обычно реализуются как Линейные конгруэнтные генераторы. Они не являются действительно случайными и, возможно, лучше называются psuedo-random.
Вероятно, вы видели разные результаты на разных машинах, потому что либо они использовали разные алгоритмы генерации псевдослучайных чисел, либо не поставляли фиксированное семя, и в этом случае текущее системное время часто является семенем по умолчанию.
Если вам нужен фиксированный набор psuedo-случайных данных, затем сгенерируйте его один раз и сохраните.
Ответ 3
Ответ: да, вы получаете повторяемую последовательность, если вы всегда используете одну и ту же реализацию и одно и то же семя, хотя это может быть нелогично из-за возможного низкого качества rand()
.
Лучше использовать структуру случайных чисел С++ в <random>
. Он не только позволяет воспроизводимые последовательности во всех реализациях, но и обеспечивает все необходимое для надежного получения дистрибутива, который вы действительно хотите.
Теперь к деталям:
Требованиями rand
являются:
- Генерирует псевдослучайные числа.
- Диапазон от 0 до
RAND_MAX
(минимум 32767).
- Семя, заданное
srand()
, определяет последовательность возвращаемых псевдослучайных чисел.
Нет необходимости в реализации PRNG, поэтому каждая реализация может иметь свои собственные, хотя Линейные конгруэнтные генераторы являются фаворитами.
Соответствующая (хотя и бесполезная) реализация представлена в этой полосе разведения:
http://dilbert.com/strips/comic/2001-10-25/
Или для тех, кто любит XKCD (это идеальное дополнение для любой библиотеки C или С++; -)):
Для полноты стандартные кавычки:
7.22.2.1 Функция rand
Функция rand вычисляет последовательность псевдослучайных целых чисел в диапазоне от 0 до RAND_MAX.
[...]
Значение макроса RAND_MAX должно быть не менее 32767.
7.22.2.2 Функция srand
Функция srand использует аргумент в качестве семени для новой последовательности псевдослучайных числа, которые будут возвращены последующими вызовами rand. Если srand затем вызывается с помощью одно и то же значение семени, последовательность псевдослучайных чисел должна повторяться. Если rand вызывается до того, как были сделаны какие-либо вызовы srand, должна быть сгенерирована одна и та же последовательность как когда srand сначала вызывается с начальным значением 1.
Ответ 4
Если вы засеваете генератор случайных чисел с тем же значением, он даст тот же результат. Вы видели разные результаты на разных машинах, потому что они (вероятно) использовали разные алгоритмы генерации случайных чисел.