Angenommen, Sie möchten C ++ - Funktionen <random>
in einem praktischen Programm verwenden (für eine Definition von "praktisch" - die Einschränkungen hier sind Teil dieser Frage). Sie haben ungefähr folgenden Code:
int main(int argc, char **argv) {
int seed = get_user_provided_seed_value(argc, argv);
if (seed == 0) seed = std::random_device()();
ENGINE g(seed); // TODO: proper seeding?
go_on_and_use(g);
}
Meine Frage ist, für welchen Typ sollten Sie verwenden ENGINE
?
Ich habe immer gesagt,
std::mt19937
weil es schnell zu tippen war und eine Namenserkennung hatte. Aber heutzutage scheinen alle zu sagen, dass der Mersenne Twister sehr schwer und cache-unfreundlich ist und nicht einmal alle statistischen Tests besteht, die andere durchführen.Ich möchte sagen,
std::default_random_engine
weil es die offensichtliche "Standardeinstellung" ist. Aber ich weiß nicht, ob es von Plattform zu Plattform unterschiedlich ist. und ich weiß nicht, ob es statistisch etwas Gutes ist.Da jeder in diesen Tagen auf einer 64-Bit - Plattform ist, sollten wir zumindest sein mit
std::mt19937_64
überstd::mt19937
?Ich würde gerne sagen
pcg64
oderxoroshiro128
weil sie angesehen und leicht erscheinen, aber sie existieren nicht in<random>
überhaupt nicht.Ich weiß nichts über
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
etc. - sicher müssen sie für etwas gut sein?
Offensichtlich gibt es hier einige konkurrierende Einschränkungen.
Stärke des Motors. (
<random>
hat keine kryptografisch starken PRNGs, aber dennoch sind einige der standardisierten "schwächer" als andere, oder?)sizeof
der Motor.Geschwindigkeit seiner
operator()
.Einfache Aussaat.
mt19937
ist notorisch schwer richtig zu säen, weil es so viel Zustand zu initialisieren hat.Portabilität zwischen Bibliotheksanbietern. Wenn ein Anbieter
foo_engine
andere Nummern produziert als ein anderer Anbieterfoo_engine
, ist dies für einige Anwendungen nicht gut. (Hoffentlich schließt dies nichts aus, außer vielleichtdefault_random_engine
.)
Wenn Sie all diese Einschränkungen so gut wie möglich abwägen, was ist Ihrer Meinung nach die ultimative Antwort "Best Practice, innerhalb der Standardbibliothek zu bleiben"? Soll ich einfach weiter benutzen std::mt19937
oder was?