Je lisais le C FAQ et découvert dans un question qu'elle me recommande d'utiliser Le raisonnement pour cela est que lorsque J'ai testé les différentes approches avec La sortie est ceci (sur ma machine GNU / Linux): P> rand () / (rand_max / n + 1) code> au lieu de la manière la plus populaire" code> rand () % N code>.
n code> est un nombre bas
rand ()% n code> n'utilisera que quelques bits de
rand () code>. p>
n code> étant
2 code> sur Windows et Linux mais ne pouvait pas remarquer une différence . p>
rand() % N:
1 0 1 1 1 1 0 0 1 1 0 1 0 1 1 0 0 0 0 0 1 0 1 1 0 0 0 1 1 1 1 0 0 0 1 1 1 0 1 0
rand() / (RAND_MAX / N + 1):
1 0 1 1 1 0 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 0 1 0 0 0 0 1 0 1 1 1 0 1 1 0 1 0 1
3 Réponses :
si Sinon, vous rencontrez dans Ce problème , quelle que soit la qualité de Malheureusement, Le problème décrit ci-dessus est vraiment fondamental, il n'existe aucun moyen de distribuer uniformément des valeurs différentes sur les résultats de y à moins que y divise X. Vous pouvez le réparer en rejetant une partie des échantillons aléatoires, pour faire diviser y le nouveau x . p> n code> est une puissance de deux, l'utilisation de la technique de reste est généralement sûre (
rand_max code> est généralement une puissance de deux moins 1, la plage complète a donc une puissance. de deux longueurs). Plus généralement,
n code> doit diviser la plage de
rand () code> afin d'éviter le biais. P>
rand () code>. En bref, le problème est que vous découpez que vous coupez cette plage dans un certain nombre de "parties" chacune de la longueur
n code>, si
n code> ne divise pas la plage puis la dernière partie ne sera pas complet. Les chiffres qui ont "coupé" de cette partie sont donc moins susceptibles de se produire, car ils ont une "pièce" en moins, ils peuvent être générés à partir de. P>
rand () / (rand_max / n + 1) code> est également cassé (de la même manière), la réponse réelle est donc: n'utilisez pas d'entre eux. P >
Envisagez d'ajouter un bref résumé du problème ici, car les liens peuvent mourir.
Il y a un autre problème avec Pour SIMPLICITY'S SAKE ''s Faire semblant Si vous avez rand ()% n code> qui introduit un biais de modulo. p>
Rand_max Code> est de 7 et n est 6. Vous voulez que les numéros 0, 1, 2, 3, 4, 5 doivent apparaître dans le flux aléatoire avec une probabilité égale. Cependant, 0 et 1 apparaîtront 1/4 du temps et les autres numéros seulement 1/8 du temps car 6 et 7 ont des restes 0 et 1 respectivement. Vous devez utiliser l'autre méthode, mais soigneusement car la troncature des fractions pourrait introduire un problème similaire. P>
arc4random_uniform () code> pour réaliser une distribution impartiale sans avoir à faire attention. p>
@David Eisenstat Les nombres aléatoires ne sont pas des distributions uniformes, mais un échantillon très important devrait l'approcher statistiquement.
Oui. La troncature des fractions pourrait introduire un problème similaire. Mais cela est plus répandu. La première approche préjugée à des chiffres plus faibles, tandis que la deuxième approche préjeter vers des nombres répartis de manière uniforme dans la plage, ce qui pourrait constituer un meilleur comportement pour certaines applications.
sur AVR-GCC: P>
J'utilisais rand () & 0xff code> pour obtenir un nombre aléatoire de 0 à 255 et les résultats n'étaient pas bons. Il s'est avéré que l'utilisation de bits inférieurs n'est pas une méthode très fiable, souvent les mêmes valeurs. Pourrait être similaire avec modulo. P>
rand () / (rand_max / n + 1) code> a travaillé beaucoup mieux pour moi p>
Si vous êtes inquiet du hasard et de bons résultats: la page man code> sur mon Mac décrit
rand code> comme "générateur de nombres aléatoires". Voir Qu'est-ce qu'un remplacement approprié pour Rand ()? pour des alternatives.
Ce n'est pas la façon dont vous remarquez des différences dans ce scénario. Votre erreur était ceci: "Les deux alternatives semblent parfaitement aléatoires pour moi" i>. Vous avez besoin d'une approche analytique. Pensez-y comme ceci: le seul moyen de vraiment mesurer cela serait d'obtenir des statistiques sur une séquence infiniment longue.
Ceci est un mauvais exemple avec
#define n 2 code> car
rand_max code> est un nombre impair et
rand ()% n code> retournera une distribution égale de 0 et 1 compte tenu des limitations du générateur pseudo aléatoire. Il n'y a absolument aucune différence dans les deux méthodes ici, uniquement dans la séquence des résultats pseudo-aléatoires. Mais (en général) le plus grand est
n code>, plus le biais de modulo est important.