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::mt19937parce 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_engineparce 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_64Overstd::mt19937?Je voudrais dire
pcg64ouxoroshiro128parce 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?)sizeofle moteur.Vitesse de son
operator().Facilité d'ensemencement.
mt19937est notoirement difficile à semer correctement car il a tellement d'état à initialiser.Portabilité entre les fournisseurs de bibliothèques. Si un fournisseur
foo_engineproduit 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?