Angenommen, ich habe einen n-seitig geladenen Würfel, bei dem jede Seite k eine gewisse Wahrscheinlichkeit p k hat , beim Würfeln hochzukommen. Ich bin gespannt, ob es einen guten Algorithmus zum statischen Speichern dieser Informationen gibt (dh für einen festen Satz von Wahrscheinlichkeiten), damit ich einen zufälligen Würfelwurf effizient simulieren kann.
Derzeit habe ich eine O (lg n) -Lösung für dieses Problem. Die Idee ist, eine Tabelle der kumulativen Wahrscheinlichkeit der ersten k Seiten für alle k zu speichern, eine zufällige reelle Zahl im Bereich [0, 1] zu erzeugen und eine binäre Suche über die Tabelle durchzuführen, um den größten Index zu erhalten, dessen kumulativ ist Wert ist nicht größer als der gewählte Wert. Ich mag diese Lösung eher, aber es scheint seltsam, dass die Laufzeit die Wahrscheinlichkeiten nicht berücksichtigt. Insbesondere in den extremen Fällen, in denen eine Seite immer auftaucht oder die Werte gleichmäßig verteilt sind, ist es möglich, das Ergebnis des Rollens in O (1) mit einem naiven Ansatz zu generieren, obwohl meine Lösung immer noch logarithmisch viele Schritte benötigt.
Hat jemand Vorschläge, wie dieses Problem auf eine Weise gelöst werden kann, die in der Laufzeit irgendwie "anpassungsfähig" ist?
EDIT : Basierend auf den Antworten auf diese Frage habe ich einen Artikel geschrieben, der viele Ansätze für dieses Problem zusammen mit ihren Analysen beschreibt. Es sieht so aus, als ob Voses Implementierung der Alias-Methode Θ (n) Vorverarbeitungszeit und O (1) Zeit pro Würfelwurf ergibt, was wirklich beeindruckend ist. Hoffentlich ist dies eine nützliche Ergänzung zu den Informationen in den Antworten!
quelle
Antworten:
Sie suchen nach der Alias-Methode, die eine O (1) -Methode zum Generieren einer festen diskreten Wahrscheinlichkeitsverteilung (vorausgesetzt, Sie können in konstanter Zeit auf Einträge in einem Array der Länge n zugreifen) mit einer einmaligen O (n) -Einstellung bereitstellt . Sie finden es dokumentiert in Kapitel 3 (PDF) von "Non-Uniform Random Variate Generation" von Luc Devroye.
Die Idee ist, Ihr Array von Wahrscheinlichkeiten p k zu nehmen und drei neue n-Element-Arrays zu erzeugen, q k , a k und b k . Jedes q k ist eine Wahrscheinlichkeit zwischen 0 und 1, und jedes a k und b k ist eine ganze Zahl zwischen 1 und n.
Wir erzeugen Zufallszahlen zwischen 1 und n, indem wir zwei Zufallszahlen r und s zwischen 0 und 1 erzeugen. Sei i = Etage (r * N) +1. Wenn q i <s ist, geben Sie a i zurück, andernfalls geben Sie b i zurück . Die Arbeit in der Alias-Methode besteht darin, herauszufinden, wie q k , a k und b k erzeugt werden .
quelle
n
und eine ausgewählte Anzahl von Zufallszahlen, die aufgrund konstanter Faktoren bei der Implementierung von Algorithmen generiert werden sollen.Verwenden Sie einen ausgeglichenen binären Suchbaum (oder eine binäre Suche in einem Array) und erhalten Sie die Komplexität O (log n). Haben Sie einen Knoten für jedes Würfelergebnis und die Schlüssel sind das Intervall, das dieses Ergebnis auslöst.
Das Gute an dieser Lösung ist, dass sie sehr einfach zu implementieren ist, aber dennoch eine gute Komplexität aufweist.
quelle
Ich denke daran, deinen Tisch zu granulieren.
Anstatt eine Tabelle mit der Summe für jeden Würfelwert zu haben, können Sie ein ganzzahliges Array mit der Länge xN erstellen, wobei x idealerweise eine hohe Zahl ist, um die Genauigkeit der Wahrscheinlichkeit zu erhöhen.
Füllen Sie dieses Array mit dem Index (normalisiert durch xN) als kumulativen Wert und speichern Sie in jedem 'Slot' im Array den möglichen Würfelwurf, wenn dieser Index angezeigt wird.
Vielleicht könnte ich es anhand eines Beispiels einfacher erklären:
Mit drei Würfeln: P (1) = 0,2, P (2) = 0,5, P (3) = 0,3
Erstellen Sie ein Array. In diesem Fall wähle ich eine einfache Länge, z. B. 10. (dh x = 3.33333)
Um die Wahrscheinlichkeit zu ermitteln, randomisieren Sie einfach eine Zahl zwischen 0 und 10 und greifen Sie einfach auf diesen Index zu.
Diese Methode verliert möglicherweise an Genauigkeit, erhöht jedoch x und die Genauigkeit ist ausreichend.
quelle