Supposons que vous souhaitiez utiliser les fonctionnalités C ++ <random>
dans un programme pratique (pour une définition de "pratique" - les contraintes font en quelque sorte partie de cette question). Vous avez du code à peu près comme ceci:
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);
}
Ma question est, quel type devez-vous utiliser ENGINE
?
J'avais l'habitude de dire toujours
std::mt19937
parce qu'il était rapide à taper et avait une reconnaissance de nom. Mais ces jours-ci, il semble que tout le monde dit que le Mersenne Twister est très lourd et sans cache et ne passe même pas tous les tests statistiques que d'autres font.Je voudrais dire
std::default_random_engine
parce que c'est le "défaut" évident. Mais je ne sais pas si cela varie d'une plateforme à l'autre, et je ne sais pas si c'est statistiquement bon.Puisque tout le monde est sur une plate-forme 64 bits de nos jours, devrions-nous au moins utiliser
std::mt19937_64
Overstd::mt19937
?Je voudrais dire
pcg64
ouxoroshiro128
parce qu'ils semblent bien respectés et légers, mais ils n'existent pas<random>
du tout.Je ne sais rien
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
, etc. - Ils doivent sûrement être bon pour quelque chose?
De toute évidence, il existe ici des contraintes concurrentes.
Force du moteur. (
<random>
Il n'y a pas de PRNG cryptographiquement solides, mais quand même, certains standardisés sont "plus faibles" que d'autres, non?)sizeof
le moteur.Vitesse de son
operator()
.Facilité d'ensemencement.
mt19937
est notoirement difficile à semer correctement car il a tellement d'état à initialiser.Portabilité entre les fournisseurs de bibliothèques. Si un fournisseur
foo_engine
produit des numéros différents d'un autre fournisseurfoo_engine
, ce n'est pas bon pour certaines applications. (J'espère que cela n'exclut rien sauf peut-êtredefault_random_engine
.)
En pesant toutes ces contraintes du mieux que vous le pouvez, quelle serait, selon vous, la réponse ultime "meilleures pratiques restant dans la bibliothèque standard"? Dois-je continuer à utiliser std::mt19937
, ou quoi?