Почему rand () дает одну и ту же последовательность чисел при каждом запуске?

Каждый раз, когда я запускаю программу с помощью rand() она дает мне те же результаты.

Пример :

 #include  #include  using namespace std; int random (int low, int high) { if (low > high) return high; return low + (rand() % (high - low + 1)); } int main (int argc, char* argv []) { for (int i = 0; i < 5; i++) cout << random (2, 5) << endl; } 

Вывод :

 3 5 4 2 3 

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

Семя для генератора случайных чисел не задано.

Если вы вызываете srand (time (NULL)), вы получите более случайные результаты:

 #include  #include  #include  using namespace std; int main() { srand(time(NULL)); cout << rand() << endl; return 0; } 

Причина в том, что случайное число, генерируемое функцией rand (), на самом деле не является случайным. Это просто трансформация. Википедия дает лучшее объяснение значения генератора псевдослучайных чисел: детерминированный генератор случайных бит. Каждый раз, когда вы вызываете rand (), он берет семя и / или последние случайные числа (с) (стандарт C не указывает используемый алгоритм, хотя C ++ 11 имеет возможности для определения некоторых популярных алгоритмов), запускает математическая операция над этими числами и возвращает результат. Поэтому, если состояние семени одинаково каждый раз (так, как если бы вы не вызывали srand с действительно случайным числом), тогда вы всегда будете получать одинаковые «случайные» номера.

Если вы хотите узнать больше, вы можете прочитать следующее:

http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/

http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/

Если вы вызовете rand() без первого вызова srand() , он будет действовать так, как если бы вы вызывали srand(1) неявно. Соответствующий бит стандарта C99 7.20.2.2 The srand function (на основе которой cstdlib ):

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

Другими словами, вы будете получать одну и ту же последовательность каждый раз. Вы можете изменить свой main :

 int main (int argc, char* argv []) { srand (time (0)); // needs ctime header. for (int i = 0; i < 5; i++) cout << random (2, 5) << endl; wait (); } 

исправить это, если вы не запускаете его более одного раза в секунду.

Как уже упоминалось, для этого вам понадобится заголовок ctime . Вы также должны cstdlib так как в этом случае rand и srand живут. Также обычно рекомендуется использовать заголовки cXXX а не XXX.h (например, cmath а не math.h ).

Таким образом, сделав все эти изменения (и используя явные пространства имен, которые я предпочитаю, хотя другие могут и не быть), я получаю:

 #include  #include  #include  #include  void wait () { int e; std::cin >> e; } int random (int low, int high) { if (low > high) return high; return low + (std::rand() % (high - low + 1)); } int main (int argc, char* argv []) { std::srand (std::time (0)); for (int i = 0; i < 5; i++) std::cout << random (2, 5) << '\n'; wait (); } 

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

Это особенность функции rand() .

То, что у вас есть, не является генератором случайных чисел, а более строго « генератором псевдослучайных чисел » . Возможность воспроизведения одних и тех же случайных последовательностей для одного и того же семпла (вы используете srand(x) ) может быть важна для воспроизведения ошибок или сохранения состояния в программах.

Лично я использую эту функцию, чтобы иметь возможность приостанавливать / сохранять процессы рендеринга в рендерере местности на основе монтирования на карло. Хорошим побочным эффектом является то, что вы можете гарантировать различные эксперименты с monte carlo на разных машинах и, следовательно, иметь возможность генерировать гарантированные разные результаты, которые затем могут быть уменьшены на последнем этапе до конечного результата более высокого качества (конечно, вы можете впоследствии использовать его повторно это более качественный конечный результат для получения еще более качественных результатов).

Обратите внимание, однако, что ни C, ни C ++ не определяют последовательность чисел из rand() . Поэтому, если вам нужны гарантированные последовательности на разных платформах, используйте один из новых генераторов случайных чисел C ++ 11 (например, mersenne twister ), сверните свой собственный (некоторые генераторы почти тривиальны для понимания, однако, поскольку большинство из них полагаются на специфическое поведение переполнения их реализация может быть не тривиальной) или использовать сторонний компонент (например, boost :: random).

Вам нужно засеять генератор случайных чисел (см. Функцию «srand»). Предполагая, что вы не выполняете криптографию, то посев его с выходом «времени», вероятно, достаточно хорош.

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

На самом деле вы получаете случайные числа psuedo. Чтобы сделать их «более случайными», вы можете засеять генератор случайных чисел, используя что-то, что «изменяется» (чаще всего текущее время).

  • Сколько случайных элементов перед MD5 вызывает столкновения?
  • Генерирование случайного целого из диапазона
  • Генерировать N случайных и уникальных чисел в пределах диапазона
  • канонический способ рандомизации NSArray в Objective C
  • Как лаконично, переносимо и основательно семя mn19937 PRNG?
  • Генерация случайных чисел в Objective-C
  • Генерация случайных массивов без дубликатов
  • srand () - зачем вызывать его только один раз?
  • Каков правильный способ использования функции rand () в C ++?
  • Создание случайного десятичного числа в C #
  • Создайте случайную буквенно-цифровую строку в Cocoa
  • Interesting Posts

    Как использовать XSLT для создания отдельных значений

    Что такое инструмент «dumpsys» для Android ADB и каковы его преимущества?

    Как использовать радио в случае изменения?

    Как получить размеры представления?

    Java: как использовать UrlConnection для отправки запроса с авторизацией?

    Где узнать о VS отладчике «волшебные имена»

    Как работают операторы преобразования на C ++?

    Как утверждать равенство на двух classах без метода equals?

    Как преобразовать Блестящее приложение, состоящее из нескольких файлов, в легкоansible и воспроизводимый пример Shiny?

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

    Найти и удалить все каталоги с именем «test» в linux

    Вызывается ли Dispose все еще, когда исключение выбрасывается внутри оператора using?

    Почему GCC, скомпилированный программой C, нуждается в разделе .eh_frame?

    Найти метрику подобия между двумя строками

    Как сравнить 2 процессора?

    Давайте будем гением компьютера.