5.7 random -- Generowanie liczb pseudolosowych

Moduł implementuje generatory liczb pseudolosowych o różnych rozkładach. Umożliwia wybór losowej liczby całkowitej z zadanego zakresu jak również losowego elementu z podanej sekwencji przy założeniu równomiernego rozkładu prawdopodobieństwa. Implementuje również funkcję generującą losową permutację listy, działającą w miejscu, oraz funkcję wybierającą losowe elementy listy bez zwracania.

Oferuje również funkcje do obliczania rozkładów: jednorodnego, normalnego (Gaussa), długiego normalnego, ujemnego wykładniczego, gamma i beta. W celu wygenerowania rozkładów dla kątów należy użyć rozkładu von Misesa.

Prawie wszystkie funkcje modułu korzystają z bazowej funkcji random(), która generuje zmiennoprzecinkowe liczby pseudolosowe z lewostronnie domkniętego przedziału [0.0, 1.0). Język Python używa generatora o nazwie Mersenne Twister, dzięki któremu możliwe jest uzyskanie liczb zmiennoprzecinkowych o 53-bitowej precyzji, przy czym okres tego generatora wynosi 2**19937-1. Implementacja w języku C, na której generator ów bazuje, jest szybka i bezpieczna ze względu na wątki. Mersenne Twister jest jednym z najszerzej badanych generatorów spośród wszystkich obecnie istniejących. Jednakże, ze względu na fakt, że jest on całkowicie deterministyczny, nie nadaje się do wszystkich celów, a w szczególności nie nadaje się do celów kryptograficznych.

Funkcje oferowane przez moduł są w rzeczywistości metodami dowiązanymi ukrytego egzemplarza klasy random.Random. Istnieje możliwość utworzenia własnych egzemplarzy klasy Random w celu uzyskania generatorów, które nie współdzielą swojego stanu. Jest ona szczególnie użyteczna w programach wielowątkowych, w których, w celu zapewnienia, że wygenerowane sekwencje widziane przez każdy z wątków nie nachodzą na siebie, tworzy się oddzielne instancje klasy Random dla każdego wątku, a następnie używa metody jumpahead().

Klasa Random może być klasą bazową dla innych klas, które mogą używać innego generatora. W takim przypadku należy nadpisać metody random(), seed(), getstate(), setstate() oraz jumpahead().

Jako przykład takiego dziedziczenia w module random zamieszczona została klasa WichmannHill która implementuje alternatywny generator w czystym języku Python. Klasa umożliwia odtworzenie działania generatora zgodne z wcześniejszymi wersjami języka Python,które jako generatora bazowego używały implementacji algorytmu Wichmanna-Hilla. Zmieniono w wersji 2.3: Substituted MersenneTwister for Wichmann-Hill.

Funkcje rejestrujące stan:

seed([x])
Inicjalizuje podstawowy generator liczb losowych. Opcjonalny argument x może być dowolnym obiektem, na którym wywołać można funkcję skrótu (obiektem haszowalnym). Jeśli x zostanie pominięte lub ma wartość None, do inincjalizowania używany jest bieżący czas; bieżący czas używany jest również wówczas, gdy moduł jest importowany po raz pierwszy. Jeżeli x nie ma wartości None ani wartości całkowitoliczbowej, w zamian używana jest funkcja hash(x). Jeżeli argument x ma wartość całkowitoliczbową, wartość ta używana jest do zainicjalizowania w sposób bezpośredni.

getstate()
Zwraca obiekt reprezentujący bieżący wewnętrzny stan generatora. Obiekt ten może być przekazany metodzie setstate() w celu przywrócenia pobranego wcześniej stanu. Dodano w wersji 2.1.

setstate(stan)
Argument stan powinien pochodzić z wcześniejszego wywołania getstate(). Funkcja setstate() przywraca generatorowi jego wewnętrzny stan, w jakim generator znajdował się w momencie wywołania metody setstate(). Dodano w wersji 2.1.

jumpahead(n)
Zmienia wewnętrzny stan generatora na stan z dużym prawdopodobieństwem znacznie się od poprzedniego różniący. Argument n jest nieujemną liczbą całkowitą, która zostanie użyta do zmiany bieżącego wektora stanu. Właściwość ta jest szczególnie użyteczna w programach wielowątkowych, w których wykorzystuje się wiele egzemplarzy klasy Random: metody setstate() oraz seed() mogą zostać użyte do ustawienia takiego samego wewnętrznego stanu początkowego we wszystkich egzemplarzach, a dzięki metodzie jumpahead() można następnie zagwarantować, że instancje generatorów znajdą się w stanach znacznie się od siebie różniących. Dodano w wersji 2.1. Zmieniono w wersji 2.3: Zamiast przeskakiwać do określonego stanu znajdującego się n kroków dalej, metoda jumpaheadn przeskakuje do innego stanu, który z dużym prawdopodobieństwem oddalony jest od poprzedniego o wiele kroków..

Funkcje działające dla liczb całkowitych:

randrange([start,] stop[, krok])
Zwraca element losowo wybrany z zakresu range(start,stop,krok). Wywołanie metody równoważne jest wykonaniu następującego fragmentu kodu: choice(range(start, stop, krok)), z tą różnicą, że w przypadku wywołania metody randrange() nie jest tworzony obiekt zakresu. Dodano w wersji 1.5.2.

randint(a, b)
Zwraca losową liczbę całkowitą N spełniającą nierówność a <= N <= b.

Functions for sequences:

choice(seq)
Zwraca losowo wybrany element niepustej sekwencji seq

shuffle(x[, random])
Miesza elementy sekwencji x w miejscu. Opcjonalny argument random jest zeroargumentową funkcją zwracającą losową liczbę zmiennoprzecinkową z przedziału [0.0, 1.0). Domyślnie używana jest funkcja random().

Należy zauważyć, ze nawet dla małych wartości len(x), całkowita liczba permutacji sekwencji x jest większa, niż cykl większości generatorów liczb losowych. Oznacza to, że w przypadku długich sekwencji większość permutacji nie zostanie wygenerowana.

sample(populacja, k)
Zwraca listę o długości k zawierającą unikatowe elementy wybrane z sekwencji reprezentującej populację. Używana do wybierania losowych elementów bez zwracania. Dodano w wersji 2.3.

Zwrócona lista zawiera elementy wybrane z przekazanej jako argument populacji, jednak oryginalna populacja pozostaje niezmieniona. Lista wynikowa zawiera elementy uporządkowane w kolejności wynikającej z kolejności losowania elementów z populacji, wobec czego wszystkie podlisty listy wynikowej można również traktować jako próbki losowe. Pozwala to na podzielenie zwycięzców loterii (próbka) na głównego zwycięzcę oraz zwycięzców drugiej nagrody (podlisty).

Elementy populacji nie muszą być elementami haszowalnymi (tj. umożliwiającymi wywołanie na nich funkcji skrótu) ani elementami unikatowymi. Jeżeli populacja zawiera powtórzenia, wówczas każde wystąpienie powtarzającej się wartości może zostać wybrane w wyniku losowania.

Aby wybrać próbkę z zakresu liczb całkowitych, jako argumentu należy użyć funkcji xrange. W ten sposób uzyska się szybki i wydajny pamięciowo wybór próby z dużej populacji: sample(xrange(10000000), 60).

Następujące funkcje generują specyficzne rozkłady zmiennych losowych o wartościach rzeczywistych. Nazwy parametrów funkcji pochodzą od nazw odpowiednich zmiennych w równaniach opisujących rozkład, co jest dość powszechną matematyczną praktyką. Większość spośród tych równań można odnaleźć w tekstach dotyczących statystyki.

The following functions generate specific real-valued distributions. Function parameters are named after the corresponding variables in the distribution's equation, as used in common mathematical practice; most of these equations can be found in any statistics text.

random()
Zwraca kolejną losową liczbę zmiennoprzecinkową z zakresu [0.0, 1.0).

uniform(a, b)
Zwraca losową liczbę rzeczywista spełniającą nierówność a <= N < b.

betavariate(alpha, beta)
Rozkład beta. Warunki nałożone na parametry mają postać: alpha > -1 i beta > -1. Wartości zwracane należą do przedziału międzi 0 i 1.

cunifvariate(średnia, kąt)
Rozkład kołowy jednorodny.średnia jest średnim kątem, a arc jest zakresem rozkładu, którego centrum stanowi kąt średni. Obydwie wartości powinny być wyrażone w radianach, a ich wartości powinny mieścić się w przedziale 0 i pi. Zwrócone wartości należą do przedziału między średnia - kąt/2 i średnia + kąt/2 oraz są znormalizowane do wartości między 0 i pi.
Przestarzałe od wersji 2.3. Zamiast tej funkcji należy wykorzystać następujący fragment kodu: (średnia + kąt * (random.random() - 0.5)) % math.pi.

expovariate(lambd)
Rozkład wykładniczy. Argument lambd jest równy wartości 1 podzielonej przez pożądaną średnią rozkładu. (Parametr ten nazywałby się "lambda", jednak jest to słowo kluczowe w języku Python.) Zwracane wartości należą do przedziału od zera do plus nieskończoności.

gammavariate(alpha, beta)
Rozkład gamma. (Nie jest to funkcja gamma!) Warunki nakładane na parametry mają postać: alpha > 0 i beta > 0.

gauss(mu, sigma)
Rozkład Gaussa. Argument mu jest średnią rozkładu, a argument sigma określa odchylenie standardowe. Funkcja ta jest nieznacznie szybsza od zdefiniowanej poniżej funkcji normalvariate().

lognormvariate(mu, sigma)
Rozkład logarytmicznie normalny. W wyniku obliczenia logarytmu naturalnego z tego rozkładu uzyska się rozkład normalny ze średnią mu oraz odchyleniem standardowym sigma. Nie ma ograniczeń na argument mu, natomiast argument sigma powinien mieć wartość większą od zera.

normalvariate(mu, sigma)
Rozkład normalny. Argument mu jest średnią, a argument sigma jest odchyleniem standardowym.

vonmisesvariate(mu, kappa)
Argument mu jest średnim kątem wyrażonym w radianach, należącym do przedziału pomiędzy 0 i 2*pi, natomiast argument kappa stanowi parametr koncentracji, który powinien mieć wartość większą od zera. Jeżeli kappa jest równy zero, rozkład redukuje się do równomiernego rozkładu kołowego na przedziale od 0 do 2*pi.

paretovariate(alpha)
Rozkład Pareto. Argument alpha stanowi parametr kształtu.

weibullvariate(alpha, beta)
Rozkład Weibulla. Argument alpha jest parametrem skali, a beta jest parametrem kształtu.

Alternatywny generator

class WichmannHill([seed])
Klasa implementująca generator przy zastosowaniu algorytmu Wichmanna-Hilla. Posiada te same metody, jakie oferuje klasa Random oraz opisaną poniżej metodę whseed. Ponieważ klasa ta została zaimplementowana całkowicie w języku Python, nie jest bezpieczna ze względu na wątki i może wymagać zastosowania blokad między wywołaniami metod. Okres tego generatora wynosi 6.953.607.871.644, co jest wartością stosunkowo małą. Należy więc zadbać o to, aby dwie niezależne sekwencje liczb losowych nie nachodziły na siebie.

whseed([x])
Metoda ta jest przestarzała. Istnieje wyłącznie ze względu na kompatybilność na poziomie bitów z wersjami języka Python wcześniejszymi niż 2.1. W celu uzyskania szczegółowych informacji, zobacz funkcję seed. Funkcja whseed nie gwarantuje, że różne jej argumenty wygenerują różne stany generatora. Ponadto, może ona wygenerować nie więcej niż 2**24 różnych stanów wewnętrznych.

Zobacz też:

M. Matsumoto and T. Nishimura, ``Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator'', ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998.

Wichmann, B. A. & Hill, I. D., ``Algorithm AS 183: An efficient and portable pseudo-random number generator'', Applied Statistics 31 (1982) 188-190.

Zajrzyj do Informacji na temat tej publikacji... aby pomóc w jej rozwoju.