IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Nombres aleatoires en C.


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut Nombres aleatoires en C.
    Bonjour a tous,

    Je vous explique mon problème. J'aimerai générer des nombres aléatoires, compris entre 0 et 3. Le problème c'est que j'en ai besoin pour initialiser un tas de variables mais avec la solution classique (rand et time), il génère le même nombre... En gros la solution n'est pas assez rapide.

    Savez-vous comment je peut faire ? (les initialisations se font surement en moins d'un demi seconde).

    Merci d'avance.

  2. #2
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Salut,

    je suppose que tu as initialisé srand avec time ? S'il te renvoie toujours le même nombre il y a un problème. Tu peux nous montrer ton bout de code ?
    Au cas où si tu es sous linux tu peux toujours accéder à /dev/random ...

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    humm

    J'ai bêtement bricoler un truc, avec du code que j'ai recuperer a droite a gauche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int randomint(int min, int max)
    {
      //srand(time(NULL));
      int g_seed = rand()%(max-min) + min;
      g_seed = (214013*g_seed+2531011);
      return ((g_seed>>16)&0x7FFF)%(max-min) + min;
    }
    Elle fonctionne a peut pres bien sauf que je ne la comprend pas bien et quand je met par exemple: min = 0, max = 4 la fonction ne génère jamais de 3...

    edit: Le code doit être compatible Windows.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par samos2 Voir le message
    humm

    J'ai bêtement bricoler un truc, avec du code que j'ai recuperer a droite a gauche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int randomint(int min, int max)
    {
      //srand(time(NULL));
      int g_seed = rand()%(max-min) + min;
      g_seed = (214013*g_seed+2531011);
      return ((g_seed>>16)&0x7FFF)%(max-min) + min;
    }
    Elle fonctionne a peut pres bien sauf que je ne la comprend pas bien et quand je met par exemple: min = 0, max = 4 la fonction ne génère jamais de 3...

    edit: Le code doit être compatible Windows.
    pourquoi avoir mis en commentaire le srand qui sert justement à initialiser la seed afin de générer l'aspect aléatoire ?

    Le fait que tu n'aies jamais 3, tu te bases sur quoi ? Ton code peut retourner 3, puisqu'il s'agit d'un modulo 4. Encore faut-il que le nombre généré par rand soit du type 4n+3.
    Tu as réalisé 1 000 000 de tests ? des 3 tu en verras

    Enfin, à quoi servent la multiplication, le décalage à droite etc ?
    Un code rand simple, que l'on trouve partout sur internet, est le suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int rnd(int min, int max) { return rand()%(max-min) + min; }
    Mais il faut initialiser la seed du rand auparavant avec srand(time((NULL));Ce qui peut mener à cette fonction seule suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <time.h>
    #include <math.h>
    int rnd(int min, int max)
    {
      static int init = 0;
      if (init == 0)
      {
        init = 1;
        srand(time(NULL));
      }
      return rand()%(max-min) + min;
    }
    http://www.cplusplus.com/reference/c...cstdlib/srand/
    http://www.cplusplus.com/reference/c.../cstdlib/rand/
    http://www.cplusplus.com/reference/clibrary/ctime/time/
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Points : 3 352
    Points
    3 352
    Par défaut
    Alors, en dehors de la boucle qui va produite les nombres pseudo aléatoires il faut commencer par initialiser le générateur de nombres par un srand(n) où n est un unsigned int.
    On l'initialise souvent avec un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    srand ( time(NULL) );
    histoire d'être pratiquement sûr de l'initialiser avec un nombre différent sur des tests consécutifs.

    Ensuite tu utilises rand pour obtenir un npa (pas de politique juste un Nombre Pseudo Aléatoire). rand renvoie un entier entre 0 et RAND_MAX, pour en obtenir un dans la tranche [0,3] le plus simple (si tu n'as pas de contraintes sur le type de npa à produire) est de prendre rand() modulo 4 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return rand() % 4;
    Edit: grillé

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Le problème vient du fait qu'il faut utiliser srand une seule fois, en début de programme. Ça te donne un point de départ et tous les nombres pseudo-aléatoires suivants en découlent. Si tu rappelles srand(time(NULL)) dans ta fonction, bien sûr, ce ne sont pas des secondes qui vont séparer les différentes invocations de ta fonction mais des micro-secondes, au plus lent ! Donc, évidemment, tu vas te retrouver avec les mêmes chiffres à chaque fois.

    Appeler srand() en début de programme suffit… à condition de rappeler son programme à plus d'une seconde d'intervalle (pas toujours le cas quand on l'appelle en cascade depuis la ligne de commande, en faisant par exemple Up, Entrée, Up, Entrée, Up, Entrée…). Si ce n'est pas suffisant, tu peux dans un premier temps utiliser des fonctions comme gettimeofday() ou clock() qui te donneront une précision bien inférieure à la seconde. Il faut ensuite chercher de l'entropie dans un contexte extérieur à ton programme, par exemple les mouvements de la souris de l'utilisateur (« /dev/random » d'UNIX fonctionne sur ce principe) et/ou sauvegarder la graine en cours entre deux lancements du même programme.

    Attention également au biais introduit par les modulos sur rand() : si le diviseur n'est pas un diviseur de RAND_MAX+1, le domaine du résultat n'est plus uniformément réparti et certaines valeurs ont alors plus de chances d'apparaître que d'autres.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Ok, alors c'etais bien a cause du srand() (que je fesais a chaque itération)...
    La fonction que donne Bousk fonctionne parfaitement

    Sinon merci pour les réponses (très complètes).

Discussions similaires

  1. [Deb.] Nombre aleatoire bricolage a critiquer
    Par Marc_3 dans le forum C++
    Réponses: 2
    Dernier message: 15/11/2005, 19h04
  2. Nombres aléatoires
    Par bdaboah dans le forum C
    Réponses: 10
    Dernier message: 05/10/2005, 11h04
  3. [langage] générer un nombre aléatoire gaussien
    Par kayari dans le forum Langage
    Réponses: 5
    Dernier message: 23/05/2005, 08h12
  4. nombres aleatoires en plsql
    Par al85 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 29/03/2005, 19h07
  5. nombre aleatoire
    Par Bob dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 17/06/2002, 18h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo