Suponha que você queira usar os recursos do C ++ <random>em um programa prático (para alguma definição de "prático" - as restrições aqui fazem parte dessa pergunta). Você tem código mais ou menos assim:
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);
}
Minha pergunta é: para que tipo você deve usar ENGINE?
Eu costumava dizer sempre
std::mt19937porque era rápido para digitar e tinha reconhecimento de nome. Mas hoje em dia parece que todo mundo está dizendo que o Mersenne Twister é muito pesado e hostil ao cache e nem passa em todos os testes estatísticos que os outros fazem.Eu gostaria de dizer
std::default_random_engineporque é o óbvio "padrão". Mas não sei se isso varia de plataforma para plataforma e não sei se é estatisticamente bom.Como hoje em dia todo mundo está em uma plataforma de 64 bits, devemos pelo menos estar usando
std::mt19937_64demaisstd::mt19937?Eu gostaria de dizer
pcg64ouxoroshiro128porque eles parecem bem respeitados e leves, mas não existem<random>.Eu não sei nada sobre
minstd_rand,minstd_rand0,ranlux24,knuth_b, etc. - certamente eles devem ser bom para alguma coisa?
Obviamente, existem algumas restrições concorrentes aqui.
Força do motor. (
<random>não possui PRNGs criptograficamente fortes, mas ainda assim, alguns dos padronizados são "mais fracos" do que outros, certo?)sizeofo motor.Velocidade do seu
operator().Facilidade de semear.
mt19937é notoriamente difícil de propagar adequadamente porque tem muito estado para inicializar.Portabilidade entre fornecedores de bibliotecas. Se um fornecedor
foo_engineproduz números diferentes dos de outro fornecedorfoo_engine, isso não é bom para alguns aplicativos. (Espero que isso não descarte nada, exceto talvezdefault_random_engine.)
Pesando todas essas restrições da melhor maneira possível, o que você diria que é a melhor resposta para "melhor prática de permanecer dentro da biblioteca padrão"? Devo continuar usando std::mt19937ou o quê?