Załóżmy, że mamy generator losowy, który generuje liczby w zakresie o rozkładzie równomiernym i musimy wygenerować liczby losowe w zakresie o rozkładzie równomiernym.
Załóżmy, że i nie dzielą równomiernie ; aby uzyskać naprawdę jednolity rozkład , możemy zastosować metodę próbkowania odrzucania :
- jeśli jest największą liczbą całkowitą taką, że
- wybrać liczbę losową w
- jeśli to wyślij , w przeciwnym razie próbuj z innymi liczbami losowymi r ', r ", ... aż warunek zostanie spełniony
Czy próbka odrzucenia jest jedynym sposobem na uzyskanie prawdziwie jednolitego rozkładu dyskretnego?
Jeśli odpowiedź brzmi tak, dlaczego?
Uwaga: jeśli pomysł jest taki sam: wygeneruj liczbę losową w , na przykład gdzie jest liczbą losową z zakresu
Odpowiedzi:
Tak i nie, w zależności od tego, co rozumiesz przez „jedyny sposób”. Tak, ponieważ nie ma metody, która gwarantowałaby zakończenie, najlepszym, co możesz zrobić (dla ogólnych wartości i ), jest algorytm, który kończy się z prawdopodobieństwem 1. Nie, dzięki czemu „marnotrawstwo” jest tak małe jak chceszR.N R
Dlaczego gwarantowane zakończenie jest ogólnie niemożliwe
Załóżmy, że masz silnik obliczeniowy (deterministyczny maszynę Turinga czy cokolwiek pływa łodzią), plus wyrocznię, który generuje losowe elementy -elementowe zestawu . Celem jest, aby wygenerować element -elementowe zestawu . Moc twojego silnika zależy tylko od sekwencji wartości zwracanych przez wyrocznię; jest funkcją tej potencjalnie nieskończonej sekwencji .[ 0 .. R - 1 ] N [ 0 , N - 1 ] f ( r 0 , r 1 , r 2 , … )R [0..R−1] N [0,N−1] f (r0,r1,r2,…)
Załóżmy, że twój silnik woła wyrocznię co najwyżej razy. Mogą istnieć ślady, dla których wyrocznia jest nazywana mniej niż razy; jeśli tak, wywołanie dodatkowego czasu wyroczni, aby zawsze było wywoływane dokładnie razy, nie zmienia wyniku. Zatem bez utraty ogólności zakładamy, że wyrocznia nazywana jest dokładnie razy. Zatem prawdopodobieństwo wyniku jest liczbą sekwencji takich, że . Ponieważ wyrocznia jest jednorodnym generatorem losowym, każda sekwencja jest równoważna i ma prawdopodobieństwo . Stąd prawdopodobieństwo każdego wyniku ma postaćm m m x ( r 0 , … , r m - 1 ) f ( r 0 , … , r m - 1 ) = x 1 / R m A / R m A 0 R mm m m m x (r0,…,rm−1) f(r0,…,rm−1)=x 1/Rm A/Rm gdzie jest liczbą całkowitą od do .A 0 Rm
Jeśli dzieli na część , możesz wygenerować równomierny rozkład na elementów, wywołując generator losowy razy (pozostawia się to jako ćwiczenie dla czytelnika). W przeciwnym razie jest to niemożliwe: nie ma sposobu, aby uzyskać wynik z prawdopodobieństwem . Zauważ, że warunek jest równoważny stwierdzeniu, że wszystkie czynniki pierwsze są również czynnikami (jest to bardziej liberalne niż to, co napisałeś w pytaniu; na przykład możesz wybrać losowy element spośród 4 z 6-stronnym fair umrzeć, mimo że 4 nie dzieli 6).R m m N m 1 / N N RN Rm m N m 1/N N R
Zmniejszenie ilości odpadów
W swojej strategii, gdy , nie musisz ponownie losować od razu. Intuicyjnie pozostało trochę entropii w którą możesz zachować w miksie.[ kr≥kN [kN..R−1]
Załóżmy, że przez cały czas będziesz generował losowe liczby poniżej , a ty generujesz ich liczby naraz, wykonując losowania. Jeśli wykonasz proste próbkowanie odrzucenia dla tej zgrupowanej generacji, marnotrawstwo nad losuje to , tj. Reszta podzielone przez liczbę losowań. Może to być tak mały jak . Kiedy i są pierwszymi pierwszymi, możesz zmniejszyć odpady dowolnie, wybierając odpowiednio duże wartości . Dla ogólnych wartości iu d d R d - kN u d d RdmodNugcd(R,N)RNdRNgcd(R,N)N/gcd(R,N)Rd−kNud RdmodNu gcd(R,N) R N d R N , obliczenia są bardziej skomplikowane, ponieważ musisz wziąć pod uwagę generowanie i osobno, ale znowu możesz zmniejszyć odpady dowolnie, używając wystarczająco dużych grup.gcd(R,N) N/gcd(R,N)
W praktyce, nawet przy stosunkowo nieefektywnych liczbach losowych (np. W kryptografii), rzadko warto robić nic prócz prostego próbkowania odrzucenia, chyba że jest małe. Na przykład w kryptografii, gdzie jest zwykle potęgą 2, a jest zwykle setkami lub tysiącami bitów, jednolite generowanie liczb losowych zwykle przebiega przez próbkowanie z bezpośrednim odrzuceniem w pożądanym zakresie.R NN R N
źródło
Twierdzenie Shannona o kodzie źródłowym pokazuje, że w pewnym sensie potrzebujesz próbek (średnio) typu aby wygenerować losową liczbę typu . Dokładniej, Shannon podaje (nieefektywny) algorytm, który dał próbki pierwszego typu, wyprowadza próbki drugiego typu, z dużym prawdopodobieństwem. Pokazuje także, że wysyłanie próbek z dużym prawdopodobieństwem jest niemożliwe.[ 0 , … , R - 1 ] [ 0 , … , N - 1 ] m m ( log N / log R - ϵ ) m ( log N / log R + ϵ )logN/logR [0,…,R−1] [0,…,N−1] m m(logN/logR−ϵ) m(logN/logR+ϵ)
Twierdzenie Shannona działa również w bardziej ogólnym przypadku przekrzywionego rozkładu wejściowego (i prawdopodobnie również przekrzywionego rozkładu wyjściowego). W takim przypadku musisz zastąpić logarytm entropią. Podczas gdy algorytm podany w twierdzeniu jest definiowany losowo, w niektórych przypadkach można go derandomizować (kosztem nieco gorszej wydajności).
źródło
W rzeczywistości nie, próbka odrzucenia jest daleka od jedynego sposobu postępowania. Niestety, biorąc pod uwagę, że komputery przechowują wszystkie informacje jako bity, a zatem mogą manipulować tylko losowymi bitami informacji, każdy algorytm narysujący jednolitą losową zmienną z zakresu będzie nieskończony, jeśli rozwój binarnej bazy będzie nieskończony.NN N
Twierdzenie to jest klasycznym wynikiem Knutha i Yao (1976), którzy opracowali strukturę drzew DDG (drzewa generujące rozkład dyskretny).
Metody ujawnione przez Gillesa są typowym rodzajem działania, które zostało zrobione w celu zmniejszenia marnotrawstwa powstałego w wyniku odrzucenia, ale oczywiście, jeśli można wygenerować po drzewach Knutha i Yao, jest to znacznie, znacznie bardziej wydajne - średnio 96% losowych bitów są zapisane.
Podałem więcej informacji na ten temat w następującym poście CStheory .
źródło