Принудительный модуль Arc4random

Согласно этой документации,

arc4random_uniform() рекомендуется для конструкций типа arc4random() % upper_bound, поскольку он избегает "модульного смещения", когда верхняя граница не является степенью двух.

Насколько плох предвзятость? Например, если я генерирую случайные числа с верхней границей 6, то какая разница между использованием arc4random с % и arc4random_uniform()?

Ответ 1

arc4random() возвращает 32-битное целое без знака, то есть значения находятся между 0 и 2 ^ 32-1 = 4 294 967 295.

Теперь смещение возникает из-за того, что множественные подинтервалы, созданные с помощью modulo не подходят точно в произвольный выходной диапазон. Представьте себе для ясности случайный генератор, который создает числа от 0 до 198 включительно. Вы хотите цифры от 0 до 99, поэтому вы вычисляете random()% 100, от 0 до 99:

0% 100 = 0
99% 100 = 99
100% 100 = 0
198% 100 = 98

Вы видите, что 99 - это единственное число, которое может произойти только один раз, пока все другие могут встречаться дважды в беге. Это означает, что вероятность для 99 в два раза меньше, что также является наихудшим случаем в смещении, где, по крайней мере, Присутствуют 2 подинтервалы.
Поскольку все мощности, равные двум меньшим, чем диапазон интервалов, хорошо вписываются в 2 ^ 32, смещение в этом случае исчезает.

Полагают, что чем меньше результирующий набор с модулем, тем выше случайный выходной диапазон, тем меньше смещение. В вашем примере 6 - ваш верхний (я предполагаю, что 0 - нижняя граница), поэтому вы используете% 7, в результате чего 0-3 происходит 613 566 757 раз, а 4-6 - 613 566 756 раз.
Таким образом, 0-3 составляет 613 566 757/613 566 756 = 1.0000000016298 раз более вероятный чем 4-6.

Хотя кажется, что его легко уволить, некоторые эксперименты (особенно Монте-Карло эксперименты) были ошибочными именно потому, что эти, казалось бы, невероятные маленькие различия были довольно важными.

Еще хуже - смещение, если желаемый выходной диапазон больше, чем случайный целевой диапазон. Пожалуйста, прочитайте запись Fisher-Yates shuffle потому что многие покер-сайты усвоили, что нормальная линейная конгруэнтные случайные генераторы и алгоритмы плохого перетасовки привели к невозможные или очень вероятные колоды или хуже, предсказуемые колоды.