Код: Выделить всё
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution dis(0, 5);
dis(gen);
Код: Выделить всё
srand(time(NULL));
rand()%6;
Но все это верно и для нового способа: он просто имеет более блестящую оболочку.
- возвращает одно целое число без знака. Он имеет как минимум 16 бит, а возможно и 32. Этого недостаточно для заполнения 19937 бит состояния MT.
Код: Выделить всё
rd() - Использование std::mt19937 gen(rd());gen() (заполнение 32 битами и просмотр первого вывода) не дает хорошего распределения вывода. 7 и 13 никогда не могут быть первым выходом. Два семени дают 0. Двенадцать семечек дают 1226181350. (Ссылка)
- может быть, а иногда и реализуется, как простой PRNG с фиксированным начальным значением. Поэтому он может создавать одну и ту же последовательность при каждом запуске. (Ссылка) Это даже хуже, чем time(NULL).
Код: Выделить всё
std::random_device
В свете этого мой вопрос: Как можно кратко, портативно и тщательно заполнить PRNG mt19937 в C++?
Учитывая вышеизложенные проблемы, хороший ответ:
- Необходимо полностью заполнить mt19937/mt19937_64.
- Невозможно полагаться исключительно на std::random_device или time(NULL) в качестве источника энтропии.
- Не следует полагаться на Boost или другие библиотеки.
- Должен вписываться в небольшое количество строк, чтобы это выглядело красиво при копировании в ответ.
- Моя текущая мысль заключается в том, что выходные данные std::random_device могут быть объединены (возможно, с помощью XOR) с временем (NULL), значениями, полученными в результате рандомизации адресного пространства, и жестко закодированной константой (которая может быть установлена во время распределения), чтобы получить лучший способ добиться энтропии.
- не дает четкого представления о том, что может или не может делать std::random_device.
Код: Выделить всё
std::random_device::entropy()
Подробнее здесь: https://stackoverflow.com/questions/450 ... 19937-prng
Мобильная версия