Tirage uniforme d'entiers sur un intervalle quelconque
Pour tirer des entiers dans [0;n-1], on pourrait produire une fonction assez rapidement :
int randomInteger(int n)
{
return rand()%n;
}
Certes, il est évident que la fonction renvoie des entiers dans [0:n-1]. Néanmoins, cette fonction est biaisée. En effet,
supposons que RAND_MAX soit 10 et que l'on veuille faire un tirage sur [0:2], ie avec n=3. Comme RAND_MAX est 10, cela
signifie que les valeurs que rand() peut renvoyer sont 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 et 10.
•Lorsque rand() renvoie 0, 3, 6, 9, randomInteger() renvoie 0.
•Lorsque rand() renvoie 1, 4, 7, 10, randomInteger() renvoie 1.
•Lorsque rand() renvoie 2, 5, 8, randomInteger() renvoie 2.
Donc la fonction renvoie 0 avec une probabilité 4/11, 1 avec une probabilité 4/11 et 2avec une probabilité 3/11. Donc la fonction
ne tire pas les entiers de manière uniforme sur [0:2], sauf dans le cas où RAND_MAX est un entier premier (à vérifier).
Pour tirer des entiers de manière uniforme, on préférera une fonction de la forme randomInteger ci dessous :
#include <cstdlib>
#include <ctime>
#include <iostream>
double randomUniform()
{
return rand()/(double)RAND_MAX;
}
double randomUniform(double a,double b)
{
return (b-a)*randomUniform()+a;
}
long arrondir(double x)//arrondi à l'entier le plus proche