Pergunta

Eu estou tentando usar os C ++ STD TechnicalReport1 extensões para gerar números seguintes uma distribuição normal, mas este código (adaptado de este artigo ):

mt19937 eng;
eng.seed(SEED);

normal_distribution<double> dist;
// XXX if I use the one below it exits the for loop
// uniform_int<int> dist(1, 52);

for (unsigned int i = 0; i < 1000; ++i) {
  cout << "Generating " << i << "-th value" << endl;
  cout << dist(eng) << endl;
}

imprime apenas 1 mensagem de log "Gerando ...", em seguida, não sai do loop ! Se eu usar a distribuição eu comentei em vez disso, ele termina, assim que eu estou querendo saber o que eu estou fazendo errado. Alguma idéia?

Muito obrigado!

Foi útil?

Solução

Este definitivamente não pendurar o programa. Mas, não tenho certeza se ele realmente atenda às suas necessidades.

 #include <random>
 #include <iostream>

 using namespace std;

 typedef std::tr1::ranlux64_base_01 Myeng; 

 typedef std::tr1::normal_distribution<double> Mydist; 

 int main() 
 { 
      Myeng eng; 
      eng.seed(1000);
      Mydist dist(1,10); 

      dist.reset(); // discard any cached values 
      for (int i = 0; i < 10; i++)
      {
           std::cout << "a random value == " << (int)dist(eng) << std::endl; 
      }

 return (0); 
 }

Outras dicas

Eu tive o mesmo problema com o código originalmente publicado e investigou a implementação GNU de

Primeiro algumas observações: com g ++ - 4,4 e usando os códigos não reage, com g ++ - 4.5 e usando -std = c ++ 0x (ou seja, não TR1, mas a coisa real) acima código funciona

IMHO, houve uma mudança entre TR1 e c ++ 0x no que diz respeito aos adaptadores entre a geração de números aleatórios e consumo de números aleatórios - mt19937 produz números inteiros, normal_distribution consome duplos

o c ++ 0x usos adaptação automaticamente, o g ++ código TR1 não

, a fim de obter o seu código de trabalho com g ++ - 4.4 e TR1, faça o seguinte

std::tr1::mt19937 prng(seed);
std::tr1::normal_distribution<double> normal;
std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<double> > randn(prng,normal);
double r = randn();

Se a sua implementação geração de números aleatórios TR1 é buggy, você pode evitar TR1 por escrito o seu próprio gerador normal, como segue.

Gerar dois uniforme (0, 1) amostras aleatórias U e V usando qualquer gerador aleatório que você confia. Em seguida, deixou r = sqrt (-2 log (u)) e sin retorno x = r (2 pi v). (Isto é chamado o método Box-Mueller.)

Se você precisar de amostras normais amostras com média mu e sigma desvio padrão, Sigma retorno * x + mu em vez de apenas x.

Enquanto este parece ser um bug, uma confirmação rápida seria para passar o padrão 0.0, 1.0 parâmetros. normal_distribution<double>::normal_distribution() deve ser igual normal_distribution<double>::normal_distribution(0.0, 1.0)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top