Bonsoir,
existe-t-il une fonction pour générer une variable aléatoire de Bernoulli en C++?
Google ne m'a pas été d'un grand secours.
Bonne soirée.
(VA de Bernoulli: prend la valeur 1 avec la probabilité p et 0 avec la probabilité 1 − p.)
-----
Bonsoir,
existe-t-il une fonction pour générer une variable aléatoire de Bernoulli en C++?
Google ne m'a pas été d'un grand secours.
Bonne soirée.
(VA de Bernoulli: prend la valeur 1 avec la probabilité p et 0 avec la probabilité 1 − p.)
Je sais pas vraiment ce que tu attends, mais recoder une fonction de ce genre ne doit pas être très compliqué. Si tu nous donnes plus d'info avec un exemple ce sera plus parlant
de manière plus précise,
je souhaiterais avoir un fonction "Bernoulli(double p)" qui retournerait 1 avec la probabilité p et 0 avec la probabilité 1-p.
Par exemple, on considère une pièce de monnaie truquée de telle sorte qu'elle a une probabilité p de tomber sur pile et 1-p de tomber sur face. Le résultat pile étant assimilé à 1 et le résultat face étant assimilé à 1-p.
Je pense pouvoir coder une telle fonction grâce à la méthode d'inversion de variables aléatoires, mais s'il y a plus simple je suis preneur...
en fait j'ai trouvé un package sur internet qui contiendrait une telle fonction, mais je ne sais pas comment l'installer (je débute en C++, que faut il faire exactement avec les .h?):
http://www.agner.org/random/
(dans Non-uniform random number generators in C++)
Tu peux tout simplement générer une variable de loi uniforme sur [0;1] (notons la X), tu renvoies 0 si X>p et 1 si X<p. On renverra bien 1 avec proba p et 0 avec proba 1-p.
La fonction rand (initialisée par srand) va te renvoyer un entier entre 0 et un certain entier RAND_MAX : pour avoir assez de décimales, tu peux tirer un entier en 0 et 100000 puis diviser ce résultat par 100000, par exemple.
Ca donne quelque chose comme ça :
Code:#include <time.h> int bernoulli(float p) { srand ( time(NULL) ); int retour = 0, max_nb = 100000; float nb = (rand()%max_nb)/max_nb; if ( nb < p ) { retour = 1; } return retour; }
Merci!!
j'ignorais tout de la fonction rand...
faire un modulo sur le résultat de rand() fausse la distribution aléatoire.
exemple:
si RAND_MAX égale 32767 (valeur anciennement habituelle)
si on fait un modulo 30000, les nombres sortants entre 30000 et 32768 se retrouvent entre 0 et 2768, doublant ainsi la probabilité de sortie de ces nombres.
Bonjour,
Pour générer une valeur réelle dans l'intervalle [0..1], la bonne formule est :
La fonction devientCode:(double)rand()/RAND_MAX;
J'en ai sorti la ligne d'initialisation du générateur aléatoire, ce n'est pas sa placeCode:int bernoulli(double p) { int retour = 0; double nb = (double)rand()/RAND_MAX; if ( nb < p ) { retour = 1; } return retour; }
On ne doit initialiser le générateur qu'une fois, et en tout cas, pas dans une fonction qui risque d'être appelée fréquemment, avec peu d'écart de temps entre les appels.Code:srand ( time(NULL) );
Au passage : préférer l'utilisation de double plutôt que float. Pour la plupart des compilateurs, c'est le type flottant par défaut.
Effectivement, sur les machines genre PC, l'usage des float n'a plus vraiment de sens vu qu'il restreint les réels entre environ +/-10e+/-38 avec seulement 24 bits significatifs (soit même pas 7 digits) et que le compilateur par défaut fait les calculs en double, il y a donc perte de précision, risque de débordement et perte d'environ 30% en performance...
Et comme actuellement, en général:
RAND_MAX vaut 2147483647, soit 10 digits, le float ne suffit effectivement plus...
Ma remarque sur le modulo reste vraie sur le risque de "repliement" non uniforme de la distribution.
Je ne savais pas que l'utilisation des float affectait les performances, c'est bon à savoir.
Et effectivement le fait de diviser par un nombre différent de RAND_MAX risque d'affecter sérieusement la probabilité sur un grand nombre d'essai...
Bonjour,
Si ça ne changeait rien, on n'aurait pas 2 types différents.
Ce n'est pas un simple risque, c'est un fait.
Ce n'est pas la division qui pose problème, c'est le modulo ! ! !