W dokumentacji jest powiedziane, że istnieje szansa na uniform(0,1)
wygenerowanie wartości 0
i 1
.
Uruchomiłem uniform(0, 1)
10000 razy, ale nigdy nie wygenerowało zera. Nawet w przypadku uniform(0, 0.001)
.
Czy random.uniform(0,1)
kiedykolwiek można wygenerować 0
lub 1
?
python
random
uniform-distribution
Venkatesh Gandi
źródło
źródło
X ~ U(0,1)
,P(X=x)
to prawie na pewno 0, dla wszystkich wartości x. (Jest tak, ponieważ w przedziale jest nieskończenie wiele możliwych wartości.) Jeśli szukasz dokładnie 0 lub 1, powinieneś użyć innej funkcji - na przykładrandom.choice
random.uniform
?Math.random()
na przykład, jak działa w JavaScript).random.uniform(0, 1)
zwrot 0 przy pierwszym połączeniuOdpowiedzi:
uniform(0, 1)
może produkować0
, ale nigdy nie będzie produkować1
.Dokumentacja mówi, że punkt końcowy
b
mógł być włączone do wartości wytworzonych:Tak więc
uniform(0, 1)
, w0 + (1-0) * random()
uproszczeniu, formuła1 * random()
musiałaby być w stanie wytworzyć1
dokładnie. To by się stało tylko, jeślirandom.random()
jest 1.0exactly. However,
losowo ()*never* produces
1.0`.Cytując
random.random()
dokumentację :Notacja
[..., ...)
oznacza, że pierwsza wartość jest częścią wszystkich możliwych wartości, ale druga nie.random.random()
co najwyżej wytworzy wartości bardzo zbliżone do1.0
.float
Typ Pythona to zmiennoprzecinkowa wartość IEEE 754 base64 , która koduje pewną liczbę ułamków binarnych (1/2, 1/4, 1/5 itd.) , Które składają się na wartość, arandom.random()
wytworzona wartość jest po prostu sumą losowy wybór tych 53 takich frakcji od2 ** -1
(1/2) do2 ** -53
(1/9007199254740992).Jednakże, ponieważ może wytwarzać wartości bardzo blisko
1.0
, razem z zaokrąglenia błędy występujące podczas pomnożyć pływających nubmers momencie, może produkowaćb
dla pewnych wartościa
ib
. Ale0
i1
nie należą do tych wartości.Zauważ, że
random.random()
może produkować 0,0, więca
jest zawsze uwzględniany w możliwych wartościach dlarandom.uniform()
(a + (b - a) * 0 == a
). Ponieważ istnieją2 ** 53
różne wartości, którerandom.random()
mogą wytworzyć (wszystkie możliwe kombinacje tych 53 ułamków binarnych), istnieje tylko 1 na 12 ** 53
(a więc 1 na 9007199254740992) szansa na takie zdarzenie.Zatem najwyższą możliwą wartością, jaką
random.random()
można wytworzyć, jest1 - (2 ** -53)
; po prostu wybierz wystarczająco małą wartość,b - a
aby umożliwić zaokrąglanie, gdy zostanie pomnożone przez wyższerandom.random()
wartości. Im mniejszeb - a
, tym większe są szanse, że się to wydarzy:Jeśli trafisz
b = 0.0
, podzieliliśmy 1023 razy, powyższa wartość oznacza, że mieliśmy szczęście po 1019 dywizjach. Najwyższą wartością, jaką do tej pory znalazłem (uruchamianie powyższej funkcji w pętli zmax()
) jest8.095e-320
(1008 działów), ale prawdopodobnie są wyższe wartości. To gra losowa. :-)Może się to również zdarzyć, jeśli nie ma wielu dyskretnych kroków pomiędzy
a
ib
, na przykład kiedya
ib
mają wysoki wykładnik, a więc może wydawać się dalekie. Wartości zmiennoprzecinkowe są nadal jedynie przybliżeniami, a liczba wartości, które mogą kodować, jest skończona. Na przykład, istnieje tylko 1 binarna część różnicy międzysys.float_info.max
isys.float_info.max - (2 ** 970)
, więc istnieje szansa 50-50random.uniform(sys.float_info.max - (2 ** 970), sys.float_info.max)
produkujesys.float_info.max
:źródło
„Kilka razy” to za mało. 10 000 to za mało.
random.uniform
wybiera spośród 2 ^ 53 (9 007,199,254,740,992) różnych wartości. Jesteś zainteresowany dwoma z nich. Jako taki, powinieneś spodziewać się wygenerowania kilku biliardów losowych wartości przed uzyskaniem wartości dokładnie 0 lub 1. Jest to możliwe, ale jest bardzo prawdopodobne, że nigdy jej nie zaobserwujesz.źródło
uniform(0, 1)
nie da się wyprodukować1
jako wyniku. Jest tak, ponieważ funkcja jest po prostu zdefiniowana jakodef uniform(a, b): return a + (b - a) * random()
irandom()
nigdy nie może wytworzyć1.0
.Możesz spróbować wygenerować pętlę, która zlicza liczbę iteracji potrzebnych do wyświetlenia dokładnego 0 (nie).
Ponadto, jak stwierdził Hobbs, liczba
uniformly
próbkowanych wartości wynosi 9 007 199,254,740,992. Co oznacza, że prawdopodobieństwo zobaczenia 0 wynosi dokładnie 1 / 9,007,199,254,740,992. Co w ujęciu ogólnym i zaokrąglanie w górę oznacza, że będziesz potrzebować średnio 10 kwatrillionów próbek, aby znaleźć 0. Oczywiście, że możesz go znaleźć przy pierwszych 10 próbach lub nigdy.Próbkowanie 1 jest niemożliwe, ponieważ przedział zdefiniowany dla wartości jest zamykany nawiasami, dlatego nie obejmuje 1.
źródło
Pewnie. Zamiast tego byłeś już na dobrej drodze
uniform(0, 0.001)
. Po prostu ograniczaj granice na tyle, aby stało się to wcześniej.źródło