Das generieren von Zufallszahlen in C++11: wie generieren, wie funktioniert es?
Kurzem stieß ich auf neue Weise zum generieren von Zufallszahlen in C++11, konnte Sie aber nicht verdauen die Papiere, dass ich darüber gelesen (was ist das Motor, Mathematik Begriff, wie Verteilung, "wo alle ganzen zahlen, die erzeugt werden wahrscheinlich gleich").
Also kann bitte jemand erklären,
- was sind Sie?
- was hat Sie zu bedeuten?
- wie zu generieren?
- wie funktionieren Sie?
- etc
Können Sie nennen es all in one FAQ über random number generation.
- Fragen über RNGs, ohne zu wissen, was ist eine distribution, ist wie zu Fragen über expression-Parser ohne zu wissen, was ein Ausdruck ist... Der RNG-Bibliothek in C++11 richtet sich an Menschen, die wissen, einige Statistiken und eine größere Bedürfnisse als die flache Verteilung generiert
rand
haben, sollten Sie einen kurzen Blick auf wikipedia für einige grundlegende Statistik-und RNG-Konzepte, sonst wird es wirklich schwer zu erklären Sie das Grundprinzip des<random>
und die Verwendung der verschiedenen Stücke. - Kaum. Ein Kind kann begreifen, das Konzept, dass ein Würfel Zufallszahlen produziert, ohne zu verstehen, was eine distribution ist.
- und das ist, wo sein Verständnis aufhört, ist nur der erste Schritt (die Motoren), und ohne auch nur zu verstehen, warum es wichtig ist, dass Sie erzeugen eine flache Verteilung. Der rest der Bibliothek ist, bleibt ein Geheimnis, ohne das Verständnis der Distributionen und andere Konzepte der Statistik.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Frage ist viel zu breit für eine vollständige Antwort, aber lassen Sie mich cherry-pick ein paar interessante Punkte:
Warum "gleich wahrscheinlich"
Angenommen, Sie haben einen einfachen Zufallszahlengenerator, generieren Sie die zahlen 0, 1, ..., 10 mit jeweils gleicher Wahrscheinlichkeit (betrachten Sie dies als die klassische
rand()
). Jetzt willst du eine zufällige Zahl im Bereich von 0, 1, 2, die jeweils mit gleicher Wahrscheinlichkeit auf. Ihre reflexartige Reaktion wäre, zu nehmenrand() % 3
. Aber warten Sie, die Reste 0 und 1 häufiger auftreten als der Rest 2, so ist dies nicht richtig!!!!Dies ist der Grund, warum wir brauchen richtige Distributionen, die eine Quelle der uniform zufällige Ganzzahlen und biegen Sie in die von uns gewünschte Verteilung, wie
Uniform[0,2]
im Beispiel. Am besten lassen Sie diese zu einer guten Bibliothek!Motoren
Damit das Herz des ganzen die Zufälligkeit ist eine gute pseudo-random number generator, generiert eine Sequenz von zahlen, die gleichmäßig verteilt über einen bestimmten Intervall, und die idealerweise über einen sehr langen Zeitraum. Die standard-Implementierung von
rand()
ist nicht oft der beste, und so ist es gut, eine Wahl. Linear-congruential und der Mersenne-twister sind zwei gute Möglichkeiten (LG ist tatsächlich oft vonrand()
zu); wieder, es ist gut, lassen Sie die Bibliothek kümmern., Wie es funktioniert
Einfach: richten Sie zuerst einen Motor und bepflanzen es. Die Samen vollständig bestimmt, die gesamte Sequenz der "zufälligen" zahlen, so ist a) eine andere (z.B. von
/dev/urandom
) jeder Zeit, und b) speichern Sie die Samen, wenn Sie es wünschen, wieder eine Folge von zufälligen Entscheidungen.Nun können wir Verteilungen erstellen:
...Und die Verwendung der engine zu erstellen Zufallszahlen!
Parallelität
Einen weiteren wichtigen Grund zu bevorzugen
<random>
über die traditionellenrand()
ist, dass es jetzt sehr klar und offensichtlich, wie man random number generation threadsicher: Entweder jeder thread mit seinem eigenen, lokalen thread-engine, gesetzt auf eine thread-lokale Saatgut, oder synchronisieren Sie den Zugriff auf das engine-Objekt.Misc
result_type
, welches ist das richtige integral-Art zu verwenden, für die Samen. Ich glaube, ich hatte einen Kinderwagen, Umsetzung, sobald das Zwang mich zu zwingen, das Saatgut fürstd::mt19937
zuuint32_t
auf x64, schließlich sollte dies behoben werden, und man kann sagenMyRNG::result_type seed_val
und damit der Motor sehr leicht austauschbar.std::random_device
ist erwähnenswert, eher als/dev/urandom
std::random_device
gefunden werden kann hier.std::random_device
genau durch Lesen/dev/urandom
, und deshalb schlägt auf Windows (wo dieses nicht vorhanden ist). Ich kann mir vorstellen, dass eine gute Bibliothek Implementierung letzendlich egal welche Plattform-spezifischen Quelle der "echte Zufall" ist überstd::random_device
.Einen random number generator ist eine Gleichung, die, gegeben eine Zahl, geben Sie eine neue Nummer. Normalerweise werden Sie entweder die erste Zahl oder den zog so etwas wie das system Zeit.
Jedes mal, wenn Sie Fragen, für eine neue Nummer verwendet es die bisherige Anzahl der zum ausführen der Gleichung.
Einen random number generator ist nicht als sehr gut, wenn es eine Tendenz hat zu produzieren die gleiche Anzahl häufiger als andere zahlen. d.h. wenn man wollte eine zufällige Zahl zwischen eins und 5 und Sie hatten dieser Verteilung der zahlen:
2 generiert wird, WEIT öfter als jede andere Zahl, so ist es wahrscheinlicher erzeugt werden als andere zahlen. Wenn alle zahlen waren gleich, wie Sie hätten eine 20% chance, jede Zahl, jedes mal. Zu sagen, dass es einen anderen Weg, den oben genannten Verteilung ist sehr unterschiedlich, da 2 begünstigt wird. Eine distribution mit allen 20%'s wäre noch.
In der Regel, wenn Sie möchten, eine echte zufällige Zahl, die Sie ziehen könnte, Daten von so etwas wie Wetter oder andere Natürliche Quelle, anstatt ein random number generator.