std::mt19937 Класс в C++

Опубликовано: 14 Сентября, 2022

Класс std::mt19937 (начиная с C++11) является очень эффективным генератором псевдослучайных чисел и определяется в случайном заголовочном файле. Он производит 32-битные псевдослучайные числа, используя хорошо известный и популярный алгоритм, называемый алгоритмом скручивания Мерсенна. Класс std::mt19937 в основном является типом класса std::mersenne_twister_engine.

typedef mersenne_twister_engine<uint_fast32_t,
 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>
 mt19937;

Синтаксис:

mt19937 mt1(seed_value);

Здесь mt1 является экземпляром класса mt19937, и для создания всей последовательности требуется начальное значение.

Значение имени mt19937

mt19937 означает скручивание Мерсенна с длинным периодом 2 19937 – 1, что означает, что mt19937 создает последовательность 32-битных целых чисел, которая повторяется только после того, как 2 19937 – 1 число было сгенерировано.

Сходства между mt19937 и rand() и srand():

std::mt19937 делает две вещи:

  • Когда создается экземпляр объекта std::mt19937, он принимает аргумент, который используется для генерации начального значения (например, srand()).
  • Используя оператор(), он генерирует случайное число (например, rand()).

Ниже приведен пример, демонстрирующий сходство:

Будучи типом класса std::mersenne_twister_engine, он имеет те же функции-члены, что и mersenne_twister_engine. Вот список некоторых важных функций-членов:

1. (конструктор): создает объект mt19937. Он принимает либо начальное значение типа результата, либо объект начальной последовательности (аналогично функции srand()).

Пример :

2. min(): возвращает минимальное значение, которое может вернуть оператор() (равное нулю).

Пример:

3. max(): возвращает максимальное значение, которое может вернуть оператор() (то есть 2 32 – 1 = 4294967295)

Пример :

4. seed(): повторно инициализирует начальное значение объекта, либо беря начальное значение типа результата, либо беря начальный объект последовательности.

Пример :

5. operator(): генерирует псевдослучайные целые числа (аналогично функции rand()).

Пример:

Существуют также функции, не являющиеся членами, перегруженные для работы с объектом std::mt19937. Это -

  • operator<<() — перегружен, чтобы мы могли напрямую печатать значение, сгенерированное объектом mt19937, в выходной поток.
  • operator>>() — используется для извлечения начального значения из ввода.

Вот простой пример генерации псевдослучайного числа путем получения начального значения от пользователя:

Используя оператор<<() и оператор>>() :

Пример :

Зачем использовать mt19937 вместо rand()?

Хотя функцию rand() можно использовать в небольшом диапазоне, она неэффективна для генерации реальных случайных чисел. Внимательный человек может заметить повторение случайных чисел, сгенерированных функцией rand(), что очень рискованно. Принимая во внимание, что std::mt19937 имеет следующие преимущества:

  1. У него очень длинный период по сравнению с rand(). Это займет больше времени. Если бы реализация вихря Мерсенна могла генерировать 1 000 000 000 (один миллиард) псевдослучайных чисел каждую секунду, программе, генерирующей псевдослучайные числа, потребовалось бы примерно 1,3684 × 105 985 лет для повторения случайной последовательности. Поэтому можно с уверенностью предположить, что наблюдатель никогда не угадает число.
  2. Многие генераторы случайных чисел могут быть запущены одновременно с разными начальными значениями. Вот пример —
C++