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

Boost C++ Discussion :

Boost random RAPIDE ?


Sujet :

Boost C++

  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Novembre 2011
    Messages : 18
    Par défaut Boost random RAPIDE ?
    Bonjour a tous,
    Je dois réaliser des tirages dans des lois de probabilités (par exemple loi normale). J'utilise la library boost.

    Cependant le code tourne rapidement (< 1 seconde).

    Mon code pour le moment:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    double rnorm(double moy, double e_type)
    {
      boost::mt19937 rng(static_cast<long unsigned int>(std::time(0)));
      boost::normal_distribution<double>  nd(moy, e_type);
      boost::variate_generator<boost::mt19937&,
                               boost::normal_distribution<double> > var_nor(rng, nd);
      return var_nor();
    }
    Le problème est qu'en utilisant (std::time(0)) l'aléa n'intervient que toutes les secondes, or je voudrais qu'il soit plus rapide...

    Une idée??

    Merci merci,
    Nane

  2. #2
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Bonjour

    Ne créer qu'un seul moteur, une seule distribution et un seul générateur par thread.

    Tu as plusieurs solutions (plus ou moins propre), il est assez courant de faire des variables static d'une fonction ou d'une classe voire des variables plus ou moins globales.

  3. #3
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Novembre 2011
    Messages : 18
    Par défaut
    Bonjour Ehonn,
    Merci pour ta réponse,

    Mais j'aurais besoin d'un peu plus de lumière.... je suis débutante et je ne comprends pas bien ce que tu as voulu dire...

    Citation Envoyé par Ehonn Voir le message
    il est assez courant de faire des variables static d'une fonction
    Je te remercie,
    Nane

  4. #4
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Lecture de la FAQ:
    FAQ C++ - Les classes en C++ - Les données et fonctions membres statiques

    C'est la même chose pour la fonction. Dans cet exemple, la variable static i de la fonction fct ne sera déclaré qu'un seul fois dans le programme et sera réutilisable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // g++ -Wall -Wextra -std=c++11 -pedantic main.cpp -o main && ./main
    // g++ -Wall -Wextra -pedantic main.cpp -o main && ./main
     
    #include <iostream>
     
    void fct()
    {
    	static unsigned int i = 0;
     
    	std::cout << i++ << std::endl;
    }
     
    int main()
    {
    	fct();
    	fct();
    	fct();
    	fct();
    	fct();
     
    	return 0;
    }
    Voici le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ g++ -Wall -Wextra -std=c++11 -pedantic main.cpp -o main && ./main
    0
    1
    2
    3
    4

  5. #5
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Novembre 2011
    Messages : 18
    Par défaut
    Mais en utilisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    boost::mt19937 rng(static_cast<long unsigned int>(std::time(0)));
    le générateur n'est crée qu'une seule fois...
    il me semble que le problème vient de qui ne change pas assez vite...

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Ya un truc que tu ne comprends pas.

    Tu as un générateur de nombre pseudo aléatoire et meme un Mersenne Twister dans ton cas. Ce dernier doit être initialisé avec une graine.

    Comme le générateur est juste pseudo-aléatoire, si on utilisait une même graine dune exécution a l'autre, on aurait la même séquence de nombre aléatoire. Pas très glop.

    Pour éviter ca, on utilise le temps au moment de la création de l'objet qui est globalement unique dune exécution a l'autre.

    Toujours est il que la ligne (prise de ton post sur le Sdz)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static boost::mt19937 rng(static_cast<long unsigned int>(std::time(0)));
    n'est exécutée qu'une seule fois Dire que std::time(0) ne change pas assez vite ne veut rien dire puisqu'il n'on ne l'appelle qu'une SEULE ET UNIQUE FOIS

    Edit. En cas de thread, les variables sont partagées. Mais si tu utilises des threads, il faut le dire
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  7. #7
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Novembre 2011
    Messages : 18
    Par défaut
    Effectivement je n'ai pas tout compris ...

    Pour éviter ca, on utilise le temps au moment de la création de l'objet.
    qui est globalement unique dune exécution a l'autre.
    Le problème est la : lorsque je demande deux exécutions successives (en l'espace d'une seconde), les résultats sont les mêmes ...

    Voila mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void afficher(double a) {
      cout << "sortie: " << a << endl;
    }
     
    int main()
    {
      afficher(rnorm(6, 3));
    }

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Actuellement, tu fais 100 exécutions du même programme qui chacun va appeler la fonction rnorm. Donc tu construits effectivement 100 générateurs tous initialisés avec le temps courant. Mais vu que la granularité est au niveau de la seconde, ba ca coince si plusieurs exécutions se déroulent en mois d'une seconde et tu as les mêmes valeurs

    A la place, essaye d'exécuter une seule fois le programme (et donc ne construire qu'un seul générateur !) et utilise une boucle pour appeler 100 fois la fonction rnorm.

    Ceci devrait marcher
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    double rnorm(double moy, double e_type)
    {
      static boost::mt19937 rng(static_cast<long unsigned int>(std::time(0)));
      boost::normal_distribution<double>  nd(moy, e_type);
      boost::variate_generator<boost::mt19937&,
                               boost::normal_distribution<double> > var_nor(rng, nd);
      return var_nor();
    }
     
    void afficher(double a) {
      cout << "sortie: " << a << endl;
    }
     
    int main()
    {
    for(int i=0;i<100;++i)
      afficher(rnorm(6, 3));
    }
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Novembre 2011
    Messages : 18
    Par défaut
    Je crois que j'y vois un peu plus clair maintenant .


    Merci merci merci

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

Discussions similaires

  1. Boost::random : Stabilité des algo
    Par 50Nio dans le forum Boost
    Réponses: 2
    Dernier message: 09/08/2012, 10h42
  2. adapteur pour Boost random generator
    Par MoonDragon dans le forum C++/CLI
    Réponses: 0
    Dernier message: 20/04/2012, 17h49
  3. Boost random et seed
    Par omc24 dans le forum Boost
    Réponses: 0
    Dernier message: 11/01/2011, 11h55
  4. [C#.NET] Random trop rapide !
    Par Ticoche dans le forum ASP.NET
    Réponses: 3
    Dernier message: 04/07/2007, 14h54

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