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::mt19937
porque 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_engine
porque é 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_64
demaisstd::mt19937
?Eu gostaria de dizer
pcg64
ouxoroshiro128
porque 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?)sizeof
o 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_engine
produz 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::mt19937
ou o quê?