Génération aléatoire pas tellement aléatoire ....

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut !

Je suis en train de faire l'exercice du javaquarium en C++ et à l'étape de la reproduction on doit générer des poissons (issus de la reproduction d'autres poissons donc).

Pour leur donner un nom j'ai décidé de faire une fonction qui m'en retournerai un généré aléatoirement. Voici la fonction :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <random>

std::string nomAleatoire(unsigned taille)
{
    static const char alphanum[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                    "abcdefghijklmnopqrstuvwxyz";

    std::random_device rd;
    std::uniform_int_distribution<unsigned> dis(0, 52);

    std::string nom;

    for (unsigned i = 0; i < taille; ++i)
        nom += alphanum[dis(rd)];

    return nom;
}

Le problème c'est que cette fonction me renvoie toujours la même chaine : rHwsGzwL … J'utilise d'ailleurs l'aléatoire ailleurs dans mon programme (choix du sexe du poisson par ex) et pareil ça me choisi toujours la même chose …

Je compile avec g++ 4.9.2 sous windows.

Quelqu'un a une idée de pourquoi ca marche pas ? Est ce que ça vient de mon code ?

Merci !

Édité par CitronHades

+0 -0

Mon message sera court car je suis sur mon portable, désolé.

Il me semble qu'il faut initialiser la random device avec un nombre aleatoire que l'on genere avec l'entropie du système exploitation.

« La Nature est un livre écrit en langage mathématique », Galilée

+0 -0

Cette réponse a aidé l'auteur du sujet

random_device est prévu pour fournir l'entropie pour initialiser un générateur pseudo-aléatoire type mt19937.

Typiquement, il faut écrire quelque chose comme :

1
2
3
4
5
6
7
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned> dis(0, 52);

for (int i = 0; i < 10; ++i) {
  std::cout << dis(gen) << std::endl;
}

Tu as aussi un deuxième problème, c'est qu'il ne faudrait pas que tu créé un générateur à chaque fois que tu veux un nom. Pour cela, tu peux au choix passer un générateur en paramètre de ta fonction nomAleatoire ou encapsuler ta fonction dans une classe et avoir le générateur en membre de ta classe.

+2 -0
Auteur du sujet

Merci pour vos réponses !

En effet il fallait utiliser un générateur et encapsuler tout ça :) Si ca intéresse (ce qui m'étonnerai mais on sait jamais) :

Alea.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef _ALEA_HPP
#define _ALEA_HPP

#include <random>

class Alea
{
private:
    std::mt19937 m_generator;

public:
    Alea();

    template<typename T>
    T uniform_distribution(T min, T max)
    {
        std::uniform_int_distribution<T> dis(min, max);

        return dis(m_generator);
    }
};

#endif

Alea.cpp

1
2
3
4
5
6
7
#include "Alea.hpp"

Alea::Alea()
    : m_generator(std::random_device()())
{

}
+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte