Ich möchte die hervorragenden Antworten von Angry Shoe und Peterchen mit einem kurzen Überblick über den Stand der Technik im Jahr 2015 ergänzen:
Einige gute Entscheidungen
randutils
Die randutils
Bibliothek (Präsentation) ist eine interessante Neuheit, die eine einfache Oberfläche und (deklarierte) robuste Zufallsfunktionen bietet. Es hat die Nachteile, dass es eine Abhängigkeit von Ihrem Projekt hinzufügt, und da es neu ist, wurde es nicht ausführlich getestet. Da ich kostenlos (MIT-Lizenz) und nur als Header bin, denke ich, dass es einen Versuch wert ist.
Minimale Probe: ein Würfelwurf
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
Auch wenn man sich nicht für die Bibliothek interessiert, bietet die Website ( http://www.pcg-random.org/ ) viele interessante Artikel zum Thema Zufallszahlengenerierung im Allgemeinen und zur C ++ - Bibliothek im Besonderen.
Boost.Random
Boost.Random
(Dokumentation) ist die Bibliothek , die inspiriert C++11
s‘ <random>
, mit denen Aktien viel von der Schnittstelle. Während es theoretisch auch eine externe Abhängigkeit ist, Boost
hat es mittlerweile den Status einer "Quasi-Standard" -Bibliothek, und sein Random
Modul könnte als die klassische Wahl für die Erzeugung von Zufallszahlen guter Qualität angesehen werden. Es bietet zwei Vorteile in Bezug auf die C++11
Lösung:
- Es ist portabler und benötigt nur Compiler-Unterstützung für C ++ 03
- Es
random_device
verwendet systemspezifische Methoden, um eine Aussaat von guter Qualität zu ermöglichen
Der einzige kleine Fehler ist, dass das Modulangebot random_device
nicht nur Header ist, sondern kompiliert und verknüpft werden muss boost_random
.
Minimale Probe: ein Würfelwurf
#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
int main() {
boost::random::random_device rand_dev;
boost::random::mt19937 generator(rand_dev());
boost::random::uniform_int_distribution<> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Während die minimale Stichprobe gut funktioniert, sollten echte Programme zwei Verbesserungen verwenden:
- make
mt19937
a thread_local
: Der Generator ist ziemlich prall (> 2 KB) und wird besser nicht auf dem Stapel zugeordnet
- Samen
mt19937
mit mehr als einer ganzen Zahl: Der Mersenne Twister hat einen großen Zustand und kann während der Initialisierung von mehr Entropie profitieren
Einige nicht so gute Entscheidungen
Die C ++ 11-Bibliothek
Die <random>
Bibliothek ist zwar die idiomatischste Lösung, bietet aber nicht viel im Austausch für die Komplexität ihrer Schnittstelle, selbst für die Grundbedürfnisse. Der Fehler liegt darin, dass std::random_device
der Standard keine minimale Qualität für seine Ausgabe vorschreibt (solange entropy()
zurückgegeben wird 0
), und ab 2015 druckt MinGW (nicht der am häufigsten verwendete Compiler, aber kaum eine esoterische Wahl) immer 4
auf dem minimalen Sample.
Minimale Probe: ein Würfelwurf
#include <iostream>
#include <random>
int main() {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Wenn die Implementierung nicht schlecht ist, sollte diese Lösung der Boost-Lösung entsprechen, und es gelten dieselben Vorschläge.
Godots Lösung
Minimale Probe: ein Würfelwurf
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
Dies ist eine einfache, effektive und saubere Lösung. Nur ein Fehler, die Kompilierung wird eine Weile dauern - ungefähr zwei Jahre, vorausgesetzt, C ++ 17 wird rechtzeitig veröffentlicht und die experimentelle randint
Funktion wird in den neuen Standard aufgenommen. Vielleicht verbessern sich bis dahin auch die Garantien für die Aussaatqualität.
Minimale Probe: ein Würfelwurf
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
Die alte C-Lösung wird aus guten Gründen als schädlich angesehen (siehe die anderen Antworten hier oder diese detaillierte Analyse ). Dennoch hat es seine Vorteile: Es ist einfach, tragbar, schnell und ehrlich, in dem Sinne, dass bekannt ist, dass die Zufallszahlen, die man erhält, kaum anständig sind und man daher nicht versucht ist, sie für ernsthafte Zwecke zu verwenden.
Die Buchhaltungstrollösung
Minimale Probe: ein Würfelwurf
#include <iostream>
int main() {
std::cout << 9; // http://dilbert.com/strip/2001-10-25
}
Während 9 ein etwas ungewöhnliches Ergebnis für einen normalen Würfelwurf ist, muss man die hervorragende Kombination guter Eigenschaften in dieser Lösung bewundern, die es schafft, die schnellste, einfachste, cachefreundlichste und tragbarste zu sein. Wenn man 9 durch 4 ersetzt, erhält man einen perfekten Generator für jede Art von Dungeons and Dragons-Würfel, wobei die symbolbeladenen Werte 1, 2 und 3 vermieden werden. Der einzige kleine Fehler ist, dass aufgrund der schlechten Laune von Dilberts Buchhaltungstrollen Dieses Programm erzeugt tatsächlich undefiniertes Verhalten.