La façon la plus simple d'obtenir des résultats uniformément distribués à partir rand
est quelque chose comme ceci:
int limited_rand(int limit)
{
int r, d = RAND_MAX/limit;
limit *= d;
do { r = rand(); } while (r >= limit);
return r/d;
}
Le résultat sera dans la gamme 0
à limit-1
, et chacun se produira avec une probabilité égale, tant que les valeurs 0
par RAND_MAX
tous avaient une probabilité égale avec la fonction originale rand
.
D'autres méthodes telles que l'arithmétique modulaire ou la division sans la boucle I utilisée introduisent biais. Les méthodes qui passent par des intermédiaires à virgule flottante n'évitent pas ce problème. Obtenir de bons nombres à virgule flottante aléatoires de rand
est au moins aussi difficile. Utiliser ma fonction pour les nombres entiers (ou une amélioration de celle-ci) est un bon point de départ si vous voulez des flottants aléatoires.
Modifier: Voici une explication de ce que je veux dire par biais. Supposons que RAND_MAX
est 7 et que limit
est 5. Supposons (si c'est une bonne fonction rand
) que les sorties 0, 1, 2, ..., 7 soient toutes également probables. Prenant rand()%5
serait mapper 0, 1, 2, 3 et 4 à eux-mêmes, mais les cartes 5, 6 et 7 à 0, 1 et 2. Cela signifie que les valeurs 0, 1 et 2 sont deux fois plus susceptibles de s'afficher comme les valeurs 3 et 4.Un phénomène similaire se produit si vous essayez de redimensionner et de diviser, par exemple en utilisant rand()*(double)limit/(RAND_MAX+1)
Ici, 0 et 1 carte à 0, 2 et 3 carte à 1, 4 cartes à 2, 5 et 6 carte à 3, et 7 cartes à 4.
Ces effets sont quelque peu atténués par l'ampleur de RAND_MAX
, mais ils peuvent revenir si limit
est grand. Par ailleurs, comme d'autres l'ont dit, avec des PRNG à congruence linéaire (l'implémentation typique de rand
), les bits faibles ont tendance à se comporter très mal, donc en utilisant l'arithmétique modulaire quand limit
est une puissance de 2 peut éviter le problème de biais que j'ai décrit (depuis limit
divise généralement RAND_MAX+1
même dans ce cas), mais vous rencontrez un problème différent à sa place.
http://www.phanderson.com/C/random.html – miku
http://www.geekpedia.com/tutorial39_Random-Number-Generation.html – miku
http://en.wikipedia.org/wiki/List_of_random_number_generators – pmg