что именно делает random.random - PullRequest
1 голос
/ 25 декабря 2009
    random.shuffle(lst_shuffle, random.random)

Я знаю, что последняя часть является необязательным аргументом. Но что это делает именно. Я не понимаю, что это значит. Это из документов.

random.random () ¶ Возврат следующей случайной плавающей запятой число в диапазоне [0,0, 1,0).

Я также вижу это, что означает этот диапазон 0,0, 1,0?

Pseudorandom number generators
Most, if not all programming languages have libraries that include a pseudo-random
number generator. This generator usually returns a random number between 0 and 1 (not
including 1). In a perfect generator all numbers have the same probability of being selected but
in the pseudo generators some numbers have zero probability.

Ответы [ 6 ]

5 голосов
/ 25 декабря 2009

Существующие ответы хорошо справляются с конкретной задачей вопроса, но я думаю, что стоит упомянуть побочный вопрос: почему вы, скорее всего, захотите передать альтернативный «генератор случайных чисел» shuffle, а не другим функциям в модуле random. Цитируя документы :

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

Фраза «генераторы случайных чисел» здесь относится к тому, что может быть более педантично названо псевдо - генераторами случайных чисел - генераторами, которые дают хорошую имитацию случайности, но являются полностью алгоритмическими, и поэтому известны не чтобы быть "действительно случайным". Любой такой алгоритмический подход будет иметь «период» - в конце концов он начнет повторяться.

Модуль Python random использует особенно хороший и хорошо изученный псевдослучайный генератор, Mersenne Twister , с периодом 2**19937-1 - число, которое имеет более 6 тысяч цифр, когда записано в десятичных цифрах, как подтвердит len(str(2**19937-1)) ;-). На моем ноутбуке я могу генерировать около 5 миллионов таких чисел в секунду:

$ python -mtimeit -s'import random' 'random.random()'
1000000 loops, best of 3: 0.214 usec per loop

Если предположить, что намного более быстрая машина способна генерировать млрд. таких чисел в секунду, цикл будет повторяться примерно за 10 5985 лет, и наилучшая текущая оценка для возраст Вселенной чуть меньше 1,5 * 10 12 лет. Таким образом, потребуется почти невообразимое количество жизней Вселенной, чтобы достичь точки повторения ;-). Параллельное вычисление не очень поможет; По оценкам, во Вселенной примерно 10 80 атомов, поэтому даже если бы вы смогли запустить такой генератор с миллиардом в секунду на каждом атоме во Вселенной, это все равно потребовало бы более 10 5800 Время жизни вселенной, чтобы начать повторяться.

Итак, вы могли бы оправдаться, подозревая, что это беспокойство по поводу повторения является чуть-чуть теоретическим, а не практическим вопросом; -).

Тем не менее, факториалы (которые учитывают перестановки последовательности длины N) также растут довольно быстро. Twister Mersenne, например, может быть в состоянии произвести все перестановки последовательности длиной 2080, но определенно не одной длины 2081 или выше. Если бы не проблема «времени жизни Вселенной», беспокойство докторов о «даже довольно малом len (x)» было бы оправданным - мы знаем , что многие возможные перестановки никогда не могут быть достигнуты путём перетасовки с таким псевдо-RNG, как только мы получим достаточно длинную последовательность, так что можно было бы беспокоиться о том, какой уклон мы фактически вводим даже с несколькими шаффлами !: -)

os.urandom обеспечивает доступ к любым источникам физических случайностей, которые предоставляет ОС - CryptGenRandom в Windows, / dev / urandom в Linux и т. д. os.urandom дает последовательности байтов, но с помощью struct легко превратить их в случайные числа :

>>> n = struct.calcsize('I')
>>> def s2i(s): return struct.unpack('I', s)[0]
... 
>>> maxi = s2i(b'\xff'*n) + 1
>>> maxi = float(s2i(b'\xff'*n) + 1)
>>> def rnd(): return s2i(os.urandom(n))/maxi

Теперь мы можем позвонить random.shuffle(somelist, rnd) и меньше беспокоиться о предвзятости; -).

К сожалению, измерения показывают, что этот подход к ГСЧ примерно в 50 раз медленнее, чем вызовы random.random() - это может быть важным практическим соображением, если нам понадобится много случайных чисел (а если нет, беспокойство о возможной предвзятости может быть неуместным ;-). Подход os.urandom также трудно использовать предсказуемым, повторяемым образом (например, для целей тестирования), в то время как для random.random() вам нужно только указать фиксированный начальный random.seed в начале теста, чтобы гарантировать воспроизводимое поведение.

Таким образом, на практике os.urandom используется только тогда, когда вам нужны случайные числа «криптографического качества», которые не может предсказать решительный злоумышленник, и поэтому готовы заплатить практическую цену за использование вместо random.random.

4 голосов
/ 25 декабря 2009

Второй аргумент используется, чтобы указать, какой генератор случайных чисел использовать. Это может быть полезно, если вам нужно / что-то «лучше», чем random.random. В чувствительных к безопасности приложениях может потребоваться криптографически безопасный генератор случайных чисел.

Разница между random.random и random.random() заключается в том, что первый является ссылкой на функцию, которая генерирует простые случайные числа, а второй фактически вызывает эту функцию.

Если бы у вас был другой генератор случайных чисел, который вы хотели бы использовать, вы могли бы сказать

random.shuffle(x, my_random_number_function)

Что делает random.random (генератор по умолчанию), он использует алгоритм, называемый Mersenne twister , чтобы создать, казалось бы, случайное число с плавающей запятой между 0 и 1 кроме 1), все числа в этом интервале имеют равную вероятность.

То, что интервал от 0 до 1 - это просто соглашение.

1 голос
/ 25 декабря 2009

Второй аргумент - это функция, которая вызывается для получения случайных чисел, которые, в свою очередь, используются для перемешивания последовательности (первый аргумент). Функция по умолчанию, используемая, если вы не предоставляете свою собственную, - random.random.

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

И ваша настроенная функция должна будет возвращать числа в диапазоне [0,0, 1,0) - 0,0 включается, 1,0 исключается.

0 голосов
/ 25 декабря 2009

Из примера :

>>> random.random()        # Random float x, 0.0 <= x < 1.0
0.37444887175646646

Генерирует случайное число с плавающей точкой от 0 до 1.

0 голосов
/ 25 декабря 2009

Функция перемешивания зависит от RNG (генератора случайных чисел), который по умолчанию равен random.random. Второй аргумент есть, поэтому вы можете указать свой собственный ГСЧ вместо значения по умолчанию.

UPDATE:

Второй аргумент - это генератор случайных чисел, который генерирует новое случайное число в диапазоне [0,0, 1,0) каждый раз, когда вы вызываете его.

Вот пример для вас:

import random

def a():
  return 0.0

def b():
  return 0.999999999999

arr = [1,2,3]

random.shuffle(arr)
print arr # prints [1, 3, 2]

arr.sort()
print arr # prints [1, 2, 3]

random.shuffle(arr)
print arr # prints [3, 2, 1]

arr.sort()
random.shuffle(arr, a)
print arr # prints [2, 3, 1]

arr.sort()
random.shuffle(arr, a)
print arr # prints [2, 3, 1]

arr.sort()
random.shuffle(arr, b)
print arr # prints [1, 2, 3]

arr.sort()
random.shuffle(arr, b)
print arr # prints [1, 2, 3]

Так что, если функция всегда возвращает одно и то же значение, вы всегда получаете одну и ту же перестановку. Если функция возвращает случайные значения каждый раз, когда она вызывается, вы получаете случайную перестановку.

0 голосов
/ 25 декабря 2009

Документы продолжают говорить:

Необязательный аргумент random - это Функция с 0 аргументами, возвращающая случайный плавать в [0,0, 1,0); по умолчанию это является функцией random ().

Это означает, что вы можете указать собственную функцию генератора случайных чисел или указать модулю использовать функцию random по умолчанию. Второй вариант - почти всегда лучший выбор, потому что Python использует довольно хороший PRNG.

Ожидаемая функция должна возвращать псевдослучайное число с плавающей запятой в диапазоне [0.0, 1.0), что означает, что 0.0 включено, а 1.0 не включено (т. Е. 0.9999 - верное число, которое нужно вернуть, но 1.0 не является). Каждое число в этом диапазоне должно быть теоретически возвращено с равной вероятностью (т.е. это линейное распределение).

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