Какова случайность при инициализации начального числа c/c++ с небольшими значениями и более высоким?

Я использую srand(), чтобы иметь некоторую псевдослучайность в моей программе на c/c++.

Мне было интересно, имеют ли srand (1) и srand (2) случайность, очень похожую, скажем, на srand (21254) и srand (9897455)?

Потому что я запускал свою программу с небольшими разными числами для начального числа, и у меня сложилось впечатление, что это не так!

Наилучшие пожелания


person Kadiro    schedule 14.03.2017    source источник
comment
Предлагаем изучить новые функции в <random> см.: en.cppreference.com/w/cpp/ header/random особенно mt19937 Что касается rand(): Нет никаких гарантий относительно качества полученной случайной последовательности en.cppreference.com/w/cpp/numeric/random/rand   -  person Richard Critten    schedule 14.03.2017
comment
Вы не должны использовать srand с постоянным номером. Ваша программа будет давать одну и ту же последовательность при каждом запуске.   -  person mch    schedule 14.03.2017
comment
Не имеет отношения к вашему вопросу (ну, во всяком случае, к вашей возможной проблеме), но я предлагаю вам начать использовать новый классы генерации псевдослучайных чисел в C++.   -  person Some programmer dude    schedule 14.03.2017
comment
@mch В некоторых ситуациях это может быть хорошо, например, для тестирования, чтобы получить предсказуемый результат.   -  person Some programmer dude    schedule 14.03.2017
comment
Это будет зависеть от реализации. Стандарт требует очень мало srand/rand.   -  person NathanOliver    schedule 14.03.2017
comment
Я обнаружил, что rand от Microsoft, в частности, имеет большую корреляцию между начальным числом и первыми одним или двумя случайными числами. Если вы застряли с его использованием, выбросьте несколько случайных чисел, чтобы улучшить поведение.   -  person Mark Ransom    schedule 14.03.2017
comment
@JesperJuhl, не могли бы вы проверить ссылку, которую вы дали?   -  person Gian Paolo    schedule 14.03.2017
comment
Я просто оставлю это здесь: rand() считается вредным   -  person Jesper Juhl    schedule 14.03.2017
comment
Спасибо, ребята, за предложения, я использую решатель, который использует srand48(), поэтому его изменение не вариант. Это вредно?   -  person Kadiro    schedule 14.03.2017
comment
srand48() может означать, что он использует 48-битное начальное число. В большинстве реализаций rand() используется что-то вроде линейного конгруэнтного генератора, который циклически перебирает все возможные варианты. значение один раз перед повторением. Если в этой версии rand используется 48-битное начальное число, вам придется вызвать rand() 281 474 976 710 656 (281 триллион) раз, прежде чем он повторится, при условии, что он аналогичен типичным реализациям rand.   -  person rcgldr    schedule 14.03.2017


Ответы (2)


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

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

Следовательно, начальное число не влияет на «случайность» или качество псевдослучайных чисел. Вызов srand(21254) или srand(9897455) просто начинается в разных точках одной и той же последовательности.

Примечание: возможно, что конкретная реализация rand() не будет использовать этот метод: однако это маловероятно и при отсутствии каких-либо гарантий вам лучше использовать <random>библиотека, которая имеет гарантии в отношении методов, используемых для генерации случайных чисел. Классы в этой библиотеке будут создавать последовательности случайных чисел более высокого качества.

person Community    schedule 14.03.2017
comment
Я использую библиотеку/решатель, который вызывает srand48(), я проверю, имеет ли он ту же реализацию. С другой стороны, суть моего вопроса в том, что если мы используем srand(1) и предполагаем, что он сгенерирует 12 в качестве начальной точки и 600 в качестве следующего значения, будет ли srand с близким значением начального числа (2,3,4 ,..) приведет к близкому поведению, например, 14 в качестве первой точки и 650 в следующей! Они разные, но у них общий шаблон! - person Kadiro; 14.03.2017

Вы говорите в комментариях, что у вас нет возможности выбрать лучший генератор случайных чисел. Это позор, потому что C++ имеет заголовок random, начиная с C++11. , и он значительно улучшен по сравнению со старыми rand/srand.

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

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

srand(1);
cout << "throwing away " << rand() << endl;
cout << "throwing away " << rand() << endl;
cout << "using " << rand() << endl;

srand(2);
cout << "throwing away " << rand() << endl;
cout << "throwing away " << rand() << endl;
cout << "using " << rand() << endl;
person Mark Ransom    schedule 16.03.2017