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 :

Obtenir une valeur aléatoire entre 0 et 1


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Inscrit en
    Juin 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 10
    Par défaut Obtenir une valeur aléatoire entre 0 et 1
    Je sais me servir de la biblihoteque stdlib.h pour faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include<iostream>
    #include<stdlib.h>
    using namespace std;
     
    int main(void)
    {
        int v;
        srand(time(NULL));
        v-rand()%30;
        cout << v;
        return 0;
    Et ainsi obtenir un entier entre 0 et 29 mais je n'ai pas réussis à avoir un réel entre 0 et 1 (du genre 0,1257 ou pire...)

    Merci d'avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Comme les valeurs renvoyées par rand() vont de zéro à RAND_MAX, tu peux renvoyer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double d=1.0/RAND_MAX;
    cout<< rand()*d  <<endl;
    Francois
    Dernière modification par Invité ; 12/06/2009 à 10h39.

  3. #3
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Tu peux aussi consulté la faq (C il me semble) pour avoir une fonction n'introduisant pas de biais.

    edit : http://c.developpez.com/faq/index.ph...NDOM_runif_a_b

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    La bibliothèque Boost Random offre toute une panoplie de générateurs aléatoires dépassant les limites de rand() et t'évitant d'avoir à réinventer la roue. Le tutoriel Boost.Random : les nombres aléatoires de Boost peut te guider pour démarrer avec cette bibliothèque.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Il n'y a pas de biais dans la méthode précédente, ou du moins pas celui dont parle la FAQ, qui porte sur l'utilisation d'un modulo.

    A priori, pour les implémentations usuelles de rand(), rand()/(double)RAND_MAX renverra bien des nombres aléatoires extraits d'une distribution uniforme, dans le sens ou la probabilité que le nombre soit compris dans un intervalle du segment [0,1) est égal à la largeur de celui ci. Il n'y aura pas de biais, dans le sens où les moments de la distribution obtenue seront très voisins de ceux d'une distribution uniforme.

    Le problème de cette mise en oeuvre vient de la valeur de RAND_MAX, qui est souvent fixée par l'implémentation à 2^15. Cela signifie que le nomlbre aléatoire obtenu ne peut prendre que 2^15 valeurs, uniformément réparties sr l'intervalle.

    On va donc avoir des problèmes si

    1- on a besoin de plus de 2^15 valeurs différentes (le système va alors nous générer des doublons), il faut alors utiliser un générateur ayant un "rand_max" plus élevé...
    2- on veut travailler sur de tous petits intervalles, mais de toutes façons, le fait que les nombres soient représentés dans l'ordinateur sous forme de flottants pose déjà ce problème...

    Mais dans ces deux cas (qui ne se présentent en pratique que dans des cas de calculs mathématiques complexes), il vaut mieux ne pas utiliser rand(), dont l'implémentation varie d'un système à l'autre, et n'est pas toujours excellente.

    rand() reste cependant un bon choix dans la quasi totalité des cas pratiques (hors intégration monte carlo ou simulation numérique).

    Francois

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par fcharton Voir le message
    Il n'y a pas de biais dans la méthode précédente, ou du moins pas celui dont parle la FAQ, qui porte sur l'utilisation d'un modulo.
    Salut,
    Si je ne m'abuse, l'entrée de la FAQ précise bien que le biais est obtenu dès lors que tu fais un %. En d'autre terme quand le dernier bout de l'intervalle n'est pas complet.
    Dans ce que tu proposes, il s'agit juste d'une 'homothétie' qui, si mes souvenirs mathématiques ne sont pas trop rouillés, ne changent rien à la distribution uniforme.

    En revanche, tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double d=1.0/RAND_MAX;
    cout<< rand()/d  <<endl;
    Ne serait-ce pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double d=1.0/RAND_MAX;
    cout<< rand()*d  <<endl;

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Si je ne m'abuse, l'entrée de la FAQ précise bien que le biais est obtenu dès lors que tu fais un %. En d'autre terme quand le dernier bout de l'intervalle n'est pas complet.
    En fait, le biais provient de deux sources... Qui interviennent dans des cas différents

    Si ton module n'est pas un diviseur de RAND_MAX, et en particulier s'il est grand, alors on a le problème de modulo dont tu parles. Un exemple caricatural est la situation où l'on voudrait des nombres compris entre 0 et RAND_MAX-1, on aurait alors 0 avec une proba 2/RAND_MAX, et tous les autres avec une proba 1/RAND_MAX. Ce problème est d'autant plus ennuyeux que le biais porte sur les petites valeurs du générateur. Mais il est négligeable pour les petites valeurs du module.

    L'utilisation d'un modulo revient à utiliser les bits de poids faible du resultat rendu par rand(), en particulier dans le cas de petits modules. Or les implémentations de rand() (généralement des générateurs linéaires) peuvent présenter (pas toujours) des biais dans ce domaine. Là le problème se posera plutôt pour de petits modules.



    Citation Envoyé par 3DArchi Voir le message
    Dans ce que tu proposes, il s'agit juste d'une 'homothétie' qui, si mes souvenirs mathématiques ne sont pas trop rouillés, ne changent rien à la distribution uniforme.
    Exactement, ca n'introduit aucun biais supplémentaire (et ca présente l'avantage d'être rapide, portable, et très facile à adapter à d'autres intervalles).

    Citation Envoyé par 3DArchi Voir le message
    Ne serait-ce pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    double d=1.0/RAND_MAX;
    cout<< rand()*d  <<endl;
    Effectivement... C'est corrigé !

    Francois

  8. #8
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Accessoirement, pour des nombres aléatoires de meilleure qualité, le TR1 contient un header <random>, qui reprend boost.random (tu peux regarder là pour de la doc, ou si ton compilateur n'a pas TR1).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Tester si une valeur d'entrée est entière
    Par Sedrik dans le forum C++
    Réponses: 4
    Dernier message: 22/10/2007, 18h11
  2. Réponses: 5
    Dernier message: 11/10/2007, 12h29
  3. Une série de valeurs pour obtenir une valeur X
    Par Geno312 dans le forum Mathématiques
    Réponses: 22
    Dernier message: 01/10/2007, 22h09
  4. Réponses: 2
    Dernier message: 19/09/2007, 15h00
  5. comment obtenir une ligne aléatoirement
    Par titoumimi dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/05/2005, 15h52

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