Suponga que desea utilizar las <random>
instalaciones de C ++ en un programa práctico (para alguna definición de "práctico", las restricciones aquí son parte de esta pregunta). Tienes un código más o menos así:
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);
}
Mi pregunta es, ¿para qué tipo debes usar ENGINE
?
Solía decir siempre
std::mt19937
porque era rápido escribir y tenía reconocimiento de nombre. Pero en estos días parece que todos dicen que el Mersenne Twister es muy pesado y poco amigable con el caché y ni siquiera pasa todas las pruebas estadísticas que otros hacen.Me gustaría decirlo
std::default_random_engine
porque es el obvio "defecto". Pero no sé si varía de una plataforma a otra, y no sé si estadísticamente es bueno.Dado que todos están en una plataforma de 64 bits en estos días, ¿al menos deberíamos usar
std::mt19937_64
másstd::mt19937
?Me gustaría decir
pcg64
oxoroshiro128
porque parecen respetados y ligeros, pero no existen en<random>
absoluto.No sé nada acerca de
minstd_rand
,minstd_rand0
,ranlux24
,knuth_b
, etc - sin duda que debe ser bueno para algo?
Obviamente, hay algunas restricciones en competencia aquí.
Resistencia del motor. (
<random>
no tiene PRNG criptográficamente fuertes, pero aún así, algunos de los estandarizados son "más débiles" que otros, ¿verdad?)sizeof
el motor.Velocidad de su
operator()
.Facilidad de siembra.
mt19937
es notoriamente difícil de sembrar adecuadamente porque tiene mucho estado para inicializar.Portabilidad entre vendedores de bibliotecas. Si un proveedor
foo_engine
produce números diferentes de los de otro proveedorfoo_engine
, eso no es bueno para algunas aplicaciones. (Espero que esto no descarte nada excepto tal vezdefault_random_engine
).
Sopesando todas estas restricciones lo mejor que pueda, ¿cuál diría que es la respuesta definitiva de "mejor práctica para mantenerse dentro de la biblioteca estándar"? ¿Debo seguir usando std::mt19937
o qué?