Recentemente, descobri uma nova maneira de gerar números aleatórios em C ++ 11, mas não consegui digerir os artigos que li sobre isso (o que é aquele mecanismo , termo matemático como distribuição , "onde todos os inteiros produzidos são igualmente prováveis ").
Então, alguém pode explicar
- o que eles são?
- o que eles significam?
- como gerar?
- como eles funcionam?
- etc
Você pode chamar tudo em um FAQ sobre geração de números aleatórios.
rand
, você deve dar uma olhada rápida na Wikipedia para alguns conceitos básicos de estatística e RNG, caso contrário, será realmente difícil explicar a razão<random>
e o uso de suas várias partes.Respostas:
A pergunta é muito ampla para uma resposta completa, mas deixe-me escolher alguns pontos interessantes:
Por que "igualmente provável"
Suponha que você tenha um gerador de números aleatórios simples que gere os números 0, 1, ..., 10 cada com probabilidade igual (pense nisso como um clássico
rand()
). Agora você quer um número aleatório no intervalo 0, 1, 2, cada um com probabilidade igual. Sua reação automática seria aceitarrand() % 3
. Mas espere, os restos 0 e 1 ocorrem com mais freqüência do que os restantes 2, então isso não está correto!É por isso que precisamos de distribuições adequadas , que pegam uma fonte de inteiros aleatórios uniformes e os transformam em nossa distribuição desejada, como
Uniform[0,2]
no exemplo. Melhor deixar isso para uma boa biblioteca!Motores
Assim, no cerne de toda aleatoriedade está um bom gerador de números pseudo-aleatórios que gera uma sequência de números que se distribui uniformemente por um certo intervalo e que, idealmente, têm um período muito longo. A implementação padrão do
rand()
nem sempre é a melhor e, portanto, é bom ter uma escolha. Linear-congruential e o twister Mersenne são duas boas escolhas (LG também é frequentemente usado porrand()
); novamente, é bom deixar a biblioteca cuidar disso.Como funciona
Fácil: primeiro, configure um motor e semeie-o. A semente determina totalmente a sequência inteira de números "aleatórios", então a) use um diferente (por exemplo, tirado de
/dev/urandom
) a cada vez, eb) armazene a semente se desejar recriar uma sequência de escolhas aleatórias.Agora podemos criar distribuições:
... E use o motor para criar números aleatórios!
Simultaneidade
Mais uma razão importante para preferir
<random>
o tradicionalrand()
é que agora é muito claro e óbvio como tornar a geração de números aleatórios segura para thread: fornecer a cada thread seu próprio mecanismo local de thread, propagado em uma semente local de thread ou sincronizar o acesso para o objeto do motor.Misc
result_type
, que é o tipo integral correto a ser usado para a semente. Eu acho que tinha uma implementação de buggy, uma vez que me obrigou a forçar a semente parastd::mt19937
auint32_t
em x64, eventualmente, isso deve ser fixo e você pode dizerMyRNG::result_type seed_val
e, assim, fazer o motor muito facilmente substituível.fonte
std::random_device
vale a pena mencionar em vez de/dev/urandom
std::random_device
pode ser encontrado aqui .Um gerador de números aleatórios é uma equação que, dado um número, dará a você um novo número. Normalmente, você fornece o primeiro número ou é obtido de algo como a hora do sistema.
Cada vez que você pede um novo número, ele usa o número anterior para executar a equação.
Um gerador de números aleatórios não é considerado muito bom se tiver a tendência de produzir o mesmo número com mais freqüência do que outros números. ou seja, se você quisesse um número aleatório entre um e 5 e tivesse esta distribuição de números:
2 é gerado com muito mais frequência do que qualquer outro número, portanto, é mais provável que seja produzido do que outros números. Se todos os números fossem iguais, você teria 20% de chance de obter cada número todas as vezes. Dito de outra forma, a distribuição acima é muito desigual porque 2 é o preferido. Uma distribuição com todos os 20% seria uniforme.
Normalmente, se você quiser um número aleatório verdadeiro, deverá obter dados de algo como o clima ou alguma outra fonte natural, em vez de um gerador de números aleatórios.
fonte