Ich bin kürzlich auf eine neue Methode gestoßen, um Zufallszahlen in C ++ 11 zu generieren, konnte aber die Artikel , die ich darüber gelesen habe, nicht verarbeiten (was ist diese Engine , mathematischer Begriff wie Verteilung , "wo alle produzierten ganzen Zahlen gleich wahrscheinlich sind ").
Kann mir bitte jemand erklären
- was sind Sie?
- was bedeuten sie
- wie generieren?
- wie arbeiten Sie?
- etc
Sie können alles in einer FAQ zur Zufallszahlengenerierung aufrufen.
rand
, sollten Sie einen kurzen Blick auf Wikipedia werfen, um einige grundlegende statistische und RNG-Konzepte zu finden. Andernfalls ist es sehr schwierig, Ihnen die Gründe<random>
und die Verwendung der verschiedenen Teile zu erklären .Antworten:
Die Frage ist viel zu weit gefasst für eine vollständige Antwort, aber lassen Sie mich ein paar interessante Punkte herausgreifen:
Warum "gleich wahrscheinlich"
Angenommen, Sie haben einen einfachen Zufallszahlengenerator, der die Zahlen 0, 1, ..., 10 mit jeweils gleicher Wahrscheinlichkeit generiert (stellen Sie sich dies als Klassiker vor
rand()
). Jetzt möchten Sie eine Zufallszahl im Bereich 0, 1, 2 mit jeweils gleicher Wahrscheinlichkeit. Ihre Knie-Ruck-Reaktion wäre zu nehmenrand() % 3
. Aber warten Sie, die Reste 0 und 1 kommen häufiger vor als die restlichen 2, also ist das nicht korrekt!Aus diesem Grund benötigen wir geeignete Verteilungen , die eine Quelle einheitlicher zufälliger Ganzzahlen verwenden und diese wie
Uniform[0,2]
im Beispiel in unsere gewünschte Verteilung umwandeln. Überlassen Sie dies am besten einer guten Bibliothek!Motoren
Das Herzstück aller Zufälligkeit ist also ein guter Pseudozufallszahlengenerator, der eine Folge von Zahlen erzeugt, die gleichmäßig über ein bestimmtes Intervall verteilt sind und idealerweise eine sehr lange Periode haben. Die Standardimplementierung von
rand()
ist oft nicht die beste, und daher ist es gut, eine Wahl zu haben. Linear-kongruent und der Mersenne-Twister sind zwei gute Optionen (LG wird auch häufig von verwendetrand()
). Auch hier ist es gut, die Bibliothek damit umgehen zu lassen.Wie es funktioniert
Einfach: Stellen Sie zuerst einen Motor auf und setzen Sie ihn ein. Der Startwert bestimmt vollständig die gesamte Folge von "Zufallszahlen". Verwenden Sie daher
/dev/urandom
jedes Mal eine andere (z. B. entnommene ) und b) speichern Sie den Startwert, wenn Sie eine Folge von Zufallswahlen neu erstellen möchten.Jetzt können wir Distributionen erstellen:
... und benutze die Engine, um Zufallszahlen zu erstellen!
Parallelität
Ein weiterer wichtiger Grund,
<random>
den herkömmlichen zu bevorzugen,rand()
ist, dass es jetzt sehr klar und offensichtlich ist, wie die Generierung von Zufallszahlen threadsicher gemacht werden kann: Stellen Sie entweder jedem Thread eine eigene thread-lokale Engine zur Verfügung, die auf einem thread-lokalen Seed basiert, oder synchronisieren Sie den Zugriff zum Motorobjekt.Sonstiges
result_type
, was der richtige Integraltyp für das Saatgut ist. Ich glaube , ich hatte eine Buggy Umsetzung einmal die mich gezwungen , für den Samen zu zwingen ,std::mt19937
umuint32_t
auf x64, schließlich dieses Problem behoben werden soll , und man kann sagen ,MyRNG::result_type seed_val
und damit den Motor macht sehr leicht austauschbar.quelle
std::random_device
eher erwähnenswert als/dev/urandom
std::random_device
dafür finden Sie hier .Ein Zufallszahlengenerator ist eine Gleichung, die Ihnen bei gegebener Zahl eine neue Zahl gibt. Normalerweise geben Sie entweder die erste Nummer an oder sie wird aus der Systemzeit abgerufen.
Jedes Mal, wenn Sie nach einer neuen Nummer fragen, wird die vorherige Nummer verwendet, um die Gleichung auszuführen.
Ein Zufallszahlengenerator wird nicht als sehr gut angesehen, wenn er dazu neigt, dieselbe Zahl häufiger als andere Zahlen zu erzeugen. dh wenn Sie eine Zufallszahl zwischen eins und 5 wollten und diese Zahlenverteilung hatten:
2 wird weitaus häufiger generiert als jede andere Nummer, daher ist es wahrscheinlicher, dass es produziert wird als andere Nummern. Wenn alle Zahlen gleich wären, hätten Sie eine 20% ige Chance, jedes Mal jede Zahl zu erhalten. Anders ausgedrückt ist die obige Verteilung sehr ungleichmäßig, da 2 bevorzugt wird. Eine Verteilung mit allen 20% wäre gerade.
Wenn Sie eine echte Zufallszahl wünschen, ziehen Sie normalerweise Daten von etwas wie Wetter oder einer anderen natürlichen Quelle anstatt von einem Zufallszahlengenerator.
quelle