Du hast eine Münze. Sie können es so oft umdrehen, wie Sie möchten.
Sie möchten eine Zufallszahl erzeugen , , so dass ein ≤ r < b , wo r , a , b ∈ Z + .
Die Verteilung der Nummern sollte gleichmäßig sein.
Es ist einfach, wenn :
r = a + binary2dec(flip n times write 0 for heads and 1 for tails)
Was ist, wenn ?
algorithms
probability-theory
randomness
random-number-generator
Pratik Deoghare
quelle
quelle
Antworten:
Was Sie suchen, basiert auf dem Ablehnungs-Sampling oder der Accept-Reject-Methode (beachten Sie, dass die Wiki-Seite ein bisschen technisch ist).
Diese Methode ist in folgenden Situationen nützlich: Sie möchten ein zufälliges Objekt aus einer Menge auswählen ( in Ihrem Fall eine zufällige Ganzzahl in der Menge ), aber Sie wissen nicht, wie Sie das tun sollen, sondern Sie kann ein zufälliges Objekt aus einer größeren Menge auswählen, die die erste Menge enthält (in Ihrem Fall [ a , 2 k + a ] für einige k, so dass 2 k + a ≥ b ; dies entspricht k Münzwürfen).[ a , b ] [ a , 2k+ a ] k 2k+ a ≥ b k
In einem solchen Szenario wählen Sie einfach so lange Elemente aus der größeren Gruppe aus, bis Sie zufällig ein Element in der kleineren Gruppe auswählen. Wenn Ihre kleinere Menge im Vergleich zu Ihrer größeren Menge groß genug ist (in Ihrem Fall enthält höchstens doppelt so viele Ganzzahlen wie [ a , b ] , was gut genug ist), ist dies effizient.[ a , 2k+ a ] [ a , b ]
Ein alternatives Beispiel: Angenommen, Sie möchten einen zufälligen Punkt innerhalb eines Kreises mit Radius 1 auswählen. Nun ist es nicht einfach, eine direkte Methode dafür zu finden. Wir wenden uns der Accept-Reject-Methode zu: Wir tasten Punkte in einem 1 × 1-Quadrat ab, das den Kreis umgibt, und testen, ob die von uns gezogene Zahl innerhalb des Kreises liegt.
quelle
(Technik: Die Antwort passt zur Auswahl der Zahl )a ≤ x < b
Da Sie Ihre Münze so oft werfen dürfen, wie Sie möchten, können Sie Ihre Wahrscheinlichkeit so nah wie Sie möchten bestimmen, indem Sie einen Bruch wählen (mit dem binären Radix: Sie werfen die Münze für jede Ziffer nach dem Punkt) und multiplizieren Sie r mit b - a , um eine Zahl zwischen 0 und [ba-1] zu erhalten (auf eine ganze Zahl abrunden). Fügen Sie diese Nummer zu a hinzu und Sie sind fertig.r ∈ [ 0 , 1 ] r b - a ein
Beispiel : Sagen Sie . 1/3 in binär ist 0.0101010101 .... Wenn dein Flip zwischen 0 und 0.010101 liegt ... ist deine Auswahl b . wenn es beween 0.010101 .. und 0.10101010 ... Ihre Wahl wird eine + 1 , und sonst wird es sein , eine + 2 .b - a = 3 b a + 1 a + 2
Wenn Sie Ihre Münze mal werfen, wird jede Zahl zwischen a und b mit Wahrscheinlichkeit 1 ausgewähltt ein b .1b - a± 2- ( t + 1 )
quelle
Wählen Sie eine Zahl in der nächstgrößeren Potenz von 2 und verwerfen Sie Antworten, die größer als .b - a
quelle
Niemand hat dies erwähnt, also lassen Sie mich formal beweisen, dass, wenn eine Domäne ist, deren Größe keine Zweierpotenz ist, endlich viele Münzwürfe nicht ausreichen, um ein einheitlich zufälliges Mitglied von D zu erzeugen . Angenommen, Sie verwenden k Münzen, um ein Mitglied von D zu generieren . Für jedes d ∈ D hat die Wahrscheinlichkeit, dass Ihr Algorithmus d generiert, für eine ganze Zahl A die Form A / 2 k . Der Hauptsatz der Arithmetik zeigt, dass A / 2 k ≠ 1 / | D | .D D k D d∈ D d A / 2k EIN A / 2k≠ 1 / | D |
Wenn Sie unabhängige, einheitliche Stichproben von D erzeugen möchten, benötigen Sie (unter dem optimalen Algorithmus) voraussichtlich n log 2 | D | . Wenn Sie von einer Verteilung der Entropie erzeugen wollen Allgemeiner H , müssen Sie ungefähr n H Zufallsbits in Erwartung. Ein Algorithmus, der dies erreicht, ist die arithmetische Decodierung, die auf eine (scheinbar) unendliche Folge von Zufallsbits angewendet wird.n D n log2| D | H n H
quelle
Wenn ba keine Potenz von 2 ist, müssen Sie möglicherweise viele Münzen umwerfen, um ein Ergebnis zu erhalten. Sie können sogar nie ein Ergebnis erhalten, aber das ist im Extremfall unwahrscheinlich.
Methoden
Die einfachste Methode ist, eine Zahl in [a, a + 2 ^ n) zu erzeugen, wobei 2 ^ n> = ba ist, bis man zufällig in [a, b) landet. Mit dieser Methode werfen Sie viel Entropie weg.
Eine teurere Methode ermöglicht es Ihnen, die gesamte Entropie beizubehalten, wird jedoch rechnerisch sehr teuer, wenn die Anzahl der Münzwürfe / Würfelwürfe zunimmt. Intuitiv ist es so, als würde man die Münzwürfe als die Ziffern einer Binärzahl rechts vom Dezimalpunkt behandeln, diese Zahl von Basis 2 nach Basis ab konvertieren und die Ziffern dieser Zahl zurückgeben, wenn sie "hängen bleiben".
Beispiel
Der folgende Code konvertiert Rollen eines fairen n-seitigen Würfels in Rollen eines fairen m-seitigen Würfels (in Ihrem Fall n = 2, m = ab), wobei die Grenzkosten mit zunehmender Anzahl der Rollen steigen. Beachten Sie die Notwendigkeit eines Rationalen Zahlentyps mit willkürlicher Genauigkeit. Eine nette Eigenschaft ist, dass das Konvertieren von n-seitig zu m-seitig und zurück zu n-seitig den ursprünglichen Stream zurückgibt, obwohl dies möglicherweise durch ein paar Rollen verzögert wird, weil Ziffern stecken bleiben müssen.
quelle
Generieren Sie eine binäre Dezimalstelle. Anstatt sie explizit zu speichern, müssen Sie nur die möglichen Mindest- und Höchstwerte protokollieren. Wenn diese Werte in derselben Ganzzahl liegen, geben Sie diese Ganzzahl zurück. Die Skizze des Codes ist unten.
(Bearbeiten) Ausführlichere Erklärung: Angenommen, Sie möchten eine zufällige Ganzzahl von 1 bis einschließlich 3 mit einer Wahrscheinlichkeit von jeweils 1/3 generieren. Wir erzeugen dazu eine zufällige binäre Dezimalzahl real, x im Bereich (0, 1). Wenn x <1/3, gebe 1 zurück, andernfalls wenn x <2/3, gebe 2, andernfalls gebe 3 zurück. Anstatt die Ziffern für x explizit zu generieren, behalten wir nur die minimal und maximal möglichen Werte von x im Auge. Anfänglich ist der minimale Wert von x 0 und der maximale Wert 1. Wenn Sie die Köpfe zuerst umdrehen, ist die erste Stelle von x hinter dem Dezimalpunkt (in Binärform) 1. Der minimal mögliche Wert von x (in Binärform) wird dann 0,100000 = 1/2 und das Maximum ist 0,111111111 = 1. Wenn Ihr nächster Flip Tails ist, beginnt x mit 0,10. Der minimal mögliche Wert ist 0.1000000 = 1/2 und der maximal mögliche Wert ist 0.1011111 = 3/4. Der minimal mögliche Wert von x ist 1/2, damit Sie wissen, dass es Es gibt keine Chance, 1 zurückzugeben, da dies x <1/3 erfordert. Sie können immer noch 2 zurückgeben, wenn x 1/2 <x <2/3 ist, oder 3, wenn 2/3 <x <3/4 ist. Nehmen wir nun an, der dritte Flip ist Schwänze. Dann muss x mit 0.100 beginnen. Min = 0,10000000 = 1/2 und Max = 0,100111111 = 5/8. Jetzt, da 1/3 <1/2 <5/8 <2/3, wissen wir, dass x in das Intervall (1/3, 2/3) fallen muss, damit wir die Erzeugung von Ziffern von x stoppen und einfach 2 zurückgeben können.
Der Code tut dies im Wesentlichen mit der Ausnahme, dass er x nicht zwischen 0 und 1 generiert, sondern zwischen a und b, aber das Prinzip ist dasselbe.
Bemerkung: Ich habe diesen Code gegen die Accept / Reject-Methode getestet und beide ergeben gleichmäßige Verteilungen. Dieser Code erfordert weniger Münzwürfe als Accept / Reject, außer wenn b - a nahe an der nächsten Potenz von 2 liegt. Wenn Sie beispielsweise a = 0, b = 62 generieren möchten, ist Accept / Reject besser. Ich konnte nachweisen, dass dieser Code im Durchschnitt nicht mehr als 2 Münzwürfe verwenden kann, als angenommen / abgelehnt zu werden. Aus meiner Lektüre geht hervor, dass Knuth und Yao (1976) eine Methode zur Lösung dieses Problems angegeben und bewiesen haben, dass ihre Methode für die erwartete Anzahl von Münzwürfen optimal ist. Sie bewiesen ferner, dass die erwartete Anzahl von Flips größer sein muss als die Shannon-Entropie der Verteilung. Ich konnte jedoch keine Kopie des Textes des Papiers finden und wäre gespannt, was ihre Methode ist. (Update: Habe gerade eine Ausstellung von Knuth Yao 1976 hier gefunden:http://www.nrbook.com/devroye/Devroye_files/chapter_fifteen_1.pdf aber ich habe es noch nicht gelesen). Jemand erwähnte auch Han Hoshi in diesem Thread, der allgemeiner zu sein scheint und ihn mit einer voreingenommenen Münze löst. Siehe auch http://paper.ijcsns.org/07_book/200909/20090930.pdf von Pae (2009) für eine gute Diskussion der Literatur.
quelle
Die einfache Antwort?
quelle
Dies ist eine vorgeschlagene Lösung für den Fall, dass b - a nicht 2 ^ k ist. Es soll in einer festgelegten Anzahl von Schritten funktionieren (keine Notwendigkeit, Kandidaten, die außerhalb Ihres erwarteten Bereichs liegen, wegzuwerfen).
Ich bin mir jedoch nicht sicher, ob dies korrekt ist. Bitte kritisieren Sie und helfen Sie dabei, die genaue Ungleichmäßigkeit in diesem Zufallszahlengenerator (falls vorhanden) zu beschreiben und wie man sie misst / quantifiziert.
Konvertieren Sie zunächst in das äquivalente Problem der Erzeugung gleichmäßig verteilter Zufallszahlen im Bereich [0, z-1], wobei z = b - a.
Auch sei m = 2 ^ k die kleinste Potenz von 2> = z.
Gemäß der obigen Lösung haben wir bereits einen gleichmäßig verteilten Zufallszahlengenerator R (m) im Bereich [0, m - 1] (kann durch Werfen von k Münzen, eine für jedes Bit, durchgeführt werden).
Die while-Schleife wird höchstens dreimal ausgeführt und gibt die nächste Zufallszahl in festen Schritten an (bester Fall = schlechtester Fall).
Ein Testprogramm für Nummern [0,2] finden Sie hier: http://pastebin.com/zuDD2V6H
quelle
Theoretisch optimaler Algorithmus
Hier ist eine Verbesserung der anderen Antwort, die ich gepostet habe. Die andere Antwort hat den Vorteil, dass es einfacher ist, auf den allgemeineren Fall des Erzeugens einer diskreten Verteilung aus einer anderen zu erweitern. Tatsächlich ist die andere Antwort ein Sonderfall des Algorithmus, der auf Han und Hoshi zurückzuführen ist.
Der Algorithmus, den ich hier beschreiben werde, basiert auf Knuth und Yao (1976). In ihrer Arbeit haben sie auch bewiesen, dass dieser Algorithmus die minimal mögliche erwartete Anzahl von Münzwürfen erreicht.
Betrachten Sie zur Veranschaulichung die in anderen Antworten beschriebene Ablehnungsstichprobenmethode. Angenommen, Sie möchten eine von 5 Zahlen einheitlich generieren [0, 4]. Die nächste Potenz von 2 ist 8, also wirfst du die Münze dreimal und erzeugst eine Zufallszahl bis 8. Wenn die Zahl 0 bis 4 ist, gibst du sie zurück. Andernfalls werfen Sie es aus und generieren eine weitere Zahl bis zu 8 und versuchen es erneut, bis Sie erfolgreich sind. Aber wenn Sie die Zahl wegwerfen, haben Sie nur etwas Entropie verschwendet. Sie können stattdessen die Anzahl der geworfenen Münzen bestimmen, um die Anzahl der künftigen Münzwürfe zu verringern, die Sie erwartungsgemäß benötigen. Konkret: Wenn Sie die Zahl [0, 7] generiert haben, geben Sie zurück, wenn es [0, 4] ist. Ansonsten ist es 5, 6 oder 7, und Sie tun in jedem Fall etwas anderes. Wenn es 5 ist, wirf die Münze erneut und gib basierend auf dem Wurf entweder 0 oder 1 zurück. Wenn es 6 ist, Wirf die Münze und gib entweder 2 oder 3 zurück. Wenn es 7 ist, wirf die Münze um. Wenn es Köpfe sind, gebe 4 zurück, wenn es Schwänze sind, fange von vorne an.
Die übrig gebliebene Entropie aus unserem ersten fehlgeschlagenen Versuch ergab 3 Fälle (5, 6 oder 7). Wenn wir dies einfach wegwerfen, werfen wir log2 (3) Münzwürfe weg. Wir behalten es stattdessen und kombinieren es mit dem Ergebnis eines anderen Flip, um 6 mögliche Fälle (5H, 5T, 6H, 6T, 7H, 7T) zu generieren, die wir sofort erneut versuchen, eine endgültige Antwort mit Erfolgswahrscheinlichkeit 5/6 zu generieren .
Hier ist der Code:
quelle