Безопасно ли брать только несколько бит из числа, полученного с помощью Twister Mersenne
Мне приходится работать с кодом, созданным сотрудником, который сейчас на пенсии, и у меня есть несколько странных вещей, касающихся случайных чисел. В некоторых моментах он сдвигал значение, возвращаемое PRNG на 10 бит вправо, а затем использовал маску для этого значения.
Я уже видел в интернете, что некоторые PRNG имеют плохие свойства случайности с некоторыми битами в количестве, которое они генерируют (например, последний, просто чередующийся от 1 до 0), но я искал, существует ли какая-то заморочка для таких проблем на Мерсенн Твистер, но я не нашел ни одного. Кто-нибудь знает что-нибудь об этом?
2 ответа
Обычно любой бит должен быть случайным, это свойство твистера Мерсенна.
Однако (я не знаю МТ очень глубоко) у вас может быть долгосрочная зависимость между некоторыми битами. Рекомендуется использовать библиотечные функции для установки целочисленного диапазона, а не упорядочивать биты самостоятельно, или вы никогда не знаете, какие сложные свойства он может получить.
Если вы используете стандартную библиотеку C++11, просто используйте std::mt19937 вместе с std::iform_int_distribution
В частности, я не уверен насчет Мерсена Твистера, но на ум приходят типичные советы, которые можно получить при попытке получить случайное целое число в диапазоне [0, n). Если у вас есть PRNG, возвращающий целые числа с большим диапазоном, чем n, вы никогда не должны использовать по модулю для уменьшения диапазона, как
x = rand() % n;
но следует изменить масштаб
x = (int) floor(((double) rand()) / ((double) RAND_MAX)) * n);
вместо. Причина в том, что наиболее значимые биты псевдослучайного числа обычно более случайны, чем младшие биты, поэтому, хотя операция по модулю сохраняет все в порядке и освобождает число с плавающей запятой, она также отбрасывает эти ценные значащие биты.
Хотя я не знаю, что пытался сделать код, о котором вы упоминали, возможно, что смещение вправо и маскировка могли бы уменьшить диапазон случайных чисел таким образом, чтобы отбрасывать наименее значимые биты.