Максимальная длина списка для перетасовки с помощью Python random.shuffle?

У меня есть список, который я перетасовываю с помощью Python, встроенного в функцию тасования (random.shuffle)

Однако ссылка Python указывает:

Заметим, что для даже довольно малого len(x) общее число перестановок x больше, чем период большинства генераторов случайных чисел; это означает, что большинство перестановок длинной последовательности никогда не могут быть сгенерированы.

Теперь, мне интересно, что означает эта "довольно маленькая len (x)". 100, 1000, 10000,...

Ответ 1

TL; DR: он "разбивается" на списки с более чем 2080 элементами, но не слишком беспокоиться:)

Полный ответ:

Прежде всего, обратите внимание, что "перетасовка" списка может быть понята (концептуально) как порождающая все возможные перестановки элементов списков и выбор одной из этих перестановок случайным образом.

Затем вы должны помнить, что все автономные компьютеризированные генераторы случайных чисел на самом деле "псевдо" случайны. То есть они на самом деле не случайны, но полагаются на ряд факторов, чтобы попытаться создать число, которое трудно угадать в продвинутом или целенаправленно воспроизведенном. К числу этих факторов обычно относится предыдущее сгенерированное число. Таким образом, на практике, если вы используете случайный генератор непрерывно определенное количество раз, вы в конечном итоге начнете получать одну и ту же последовательность заново (это "период", на который ссылается документация).

Наконец, docstring в Lib/random.py(случайный модуль) говорит, что "Период [генератора случайных чисел] равен 2**19937-1."

Итак, учитывая все это, если ваш список таков, что есть 2**19937 или больше перестановок, некоторые из них никогда не будут получены путем перетасовки списка. Вы (опять же, концептуально) генерируете все перестановки в списке, затем генерируете случайное число x и выбираете x-ю перестановку. В следующий раз вы генерируете другое случайное число y и выбираете y-ю перестановку. И так далее. Но, поскольку есть больше перестановок, чем вы получите случайные числа (потому что, самое большее после 2**19937-1 сгенерированных чисел, вы снова начнете получать те же самые), вы снова начнете выбирать те же перестановки.

Итак, вы видите, это не вопрос о том, как долго ваш список (хотя это входит в уравнение). Кроме того, 2**19937-1 - довольно длинное число. Но, все же, в зависимости от ваших потребностей в перетасовке, вы должны помнить об этом. В упрощенном случае (и с быстрым вычислением) для списка без повторяющихся элементов 2081 элементов будут давать перестановки 2081!, что больше, чем 2**19937.

Ответ 2

Я написал этот комментарий в источнике Python изначально, так что, возможно, я могу уточнить; -)

Когда комментарий был введен, генератор Python Wichmann-Hill имел гораздо более короткий период, и мы даже не могли генерировать все перестановки колоды карт.

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

Там очень простое объяснение: PRNG периода P имеет P возможных исходных состояний. Начальное состояние полностью определяет произведенную перестановку. Поэтому PRNG периода P не может генерировать больше чем P различных перестановок (и что абсолютная верхняя граница - это может быть не достигнуто). Вот почему сравнение N! для P это правильное вычисление здесь. И действительно:

>>> math.factorial(2080) > 2**19937 - 1
False
>>> math.factorial(2081) > 2**19937 - 1
True

Ответ 3

Что они означают, так это то, что перестановки на n объектах (отмеченные n!) растут абсурдно высоко очень быстро.

В основном n!= n x n-1 x... x 1; например, 5!= 5 x 4 x 3 x 2 x 1 = 120, что означает, что существует 120 возможных способов перетасовки списка из 5 предметов.

На той же странице документации на Python они дают 2 ^ 19937-1 как период, который 4.something × 10 ^ 6001 или что-то. Основываясь на странице Википедии о факториалах, я думаю, 2000! должно быть вокруг этого. (Извините, я не нашел точную цифру.)

Таким образом, в принципе существует так много возможных перестановок, из которых будет тасоваться, что, вероятно, нет реальной причины беспокоиться о том, чего не будет.

Но если это действительно проблема (надоедливый клиент, требующий гарантии случайности, возможно?), вы также можете разгрузить задачу некоторым сторонним производителям; см. http://www.random.org/, например.