Dans une petite application écrite en C / C ++, je suis confronté à un problème avec la rand
fonction et peut-être la graine:
Je veux produire une séquence de nombres aléatoires qui sont d'ordres différents, c'est-à-dire avec des valeurs de logarithme différentes (base 2). Mais il semble que tous les nombres produits sont du même ordre, oscillant juste entre 2 ^ 25 et 2 ^ 30.
Est-ce parce que le temps rand()
est basé sur Unix qui est maintenant un nombre relativement important? Qu'est-ce que j'oublie? Je ne seme rand()
qu'une seule fois au début du main()
.
rand()
à renvoyer des nombres uniformément distribués (la documentation avec un classement Google élevé le dit explicitement), je ne pense pas que cette question soit utile pour les futurs lecteurs. C'est pourquoi voter contre mais ne laissez pas cela vous décourager d'utiliser SO.Réponses:
Il n'y a que 3% des nombres entre 1 et 2 30 qui ne sont PAS entre 2 25 et 2 30 . Donc, cela semble assez normal :)
Parce que 2 25 /2 30 = 2 -5 = 1/32 = 0,03125 = 3,125%
la source
>>
décalage de bits - cela vous donnera des nombres plus petits. (Ou en prenant un module avec%
.)0
- et si chaque bit est aléatoire ...Le vert plus clair est la région entre 0 et 2 25 ; le vert plus foncé est la région entre 2 25 et 2 30 . Les tiques sont des puissances de 2.
la source
Vous devez être plus précis: vous voulez des valeurs de logarithme de base 2 différentes mais quelle distribution voulez-vous pour cela? Les fonctions standard rand () génèrent une distribution uniforme, vous devrez transformer cette sortie en utilisant la fonction quantile associée à la distribution que vous voulez.
Si vous nous indiquez la distribution, nous pouvons vous indiquer la
quantile
fonction dont vous avez besoin.la source
Si vous voulez des ordres de grandeur différents, pourquoi ne pas simplement essayer
pow(2, rand())
? Ou peut-être choisir l'ordre directement comme rand (), comme l'a suggéré Harold?la source
rand()
peut aller jusqu'àRAND_MAX
, vous devez vraiment mettre à l'échelle votre nombre aléatoire pour que le résultat ne déborde pas ...@ C4stor a fait un excellent point. Mais, pour un cas plus général et plus facile à comprendre pour l'homme (base 10): pour la plage de 1 à 10 ^ n, ~ 90% des nombres vont de 10 ^ (n-1) à 10 ^ n, donc, ~ 99% des nombres vont de 10 ^ (n-2) à 10 ^ n. Continuez à ajouter autant de décimales que vous le souhaitez.
Mathématiques amusantes, si vous continuez à faire cela pour n, vous pouvez voir que de 1 à 10 ^ n, 99,9999 ...% = 100% des nombres vont de 10 ^ 0 à 10 ^ n avec cette méthode.
Maintenant à propos du code, si vous voulez un nombre aléatoire avec des ordres de grandeur aléatoires, de 0 à 10 ^ n, vous pouvez faire:
Génère un petit nombre aléatoire de 0 à n
Si vous connaissez la plage de n, générez un grand nombre aléatoire d'ordre 10 ^ k où k> max {n}.
Coupez le nombre aléatoire le plus long pour obtenir les n chiffres de ce grand nombre aléatoire.
la source
La réponse basique (et correcte) a déjà été donnée et acceptée ci-dessus: il y a 10 nombres entre 0 et 9, 90 nombres entre 10 et 99, 900 entre 100 et 999, etc.
Pour un moyen efficace en termes de calcul d'obtenir une distribution avec une distribution approximativement logarithmique, vous voulez décaler à droite votre nombre aléatoire d'un nombre aléatoire:
Ce n'est pas parfait, mais c'est beaucoup plus rapide que l'informatique
pow(2, rand()*scalefactor)
. Elle sera "grumeleuse" en ce sens que la distribution sera uniforme pour les nombres à l'intérieur d'un facteur 2 (uniforme pour 128 à 255, moitié de la densité pour 256 à 1023, etc.).Voici un histogramme de la fréquence des nombres de 0 à 31 (en 1M d'échantillons):
la source
rand()>>(rand()&31);
, on s'attendrait intuitivement à ce que 1/32 des nombres ait 32 bits, et 1 / 32e des nombres ait 31 bits, et 1 / 32e des nombres ait 30 bits, etc. Mais c'est pas les résultats que vous obtenez, seulement environ 1 / 64e des nombres donneraient 32 bits, tandis que près de la moitié devrait être 0. Puisque mes calculs mentaux ne sont pas d'accord avec vos mesures, je vais devoir faire mes propres mesures pour comprendre cette sortie.Il y a exactement le même nombre de nombres entre 0 et 2 ^ 29 et 2 ^ 29 et 2 ^ 30.
Une autre façon de voir le problème: considérez la représentation binaire du nombre aléatoire que vous générez, la probabilité que le bit le plus élevé soit 1 égale 1/2, et, par conséquent, vous obtenez l'ordre 29 dans la moitié des cas. Ce que vous voulez, c'est voir un nombre qui serait inférieur à 2 ^ 25, mais cela signifie que 5 bits les plus élevés sont tous à zéro, ce qui se produit avec une faible probabilité de 1/32. Il y a de fortes chances que même si vous l'exécutez pendant une longue période, vous ne verrez jamais du tout l'ordre en dessous de 15 (la probabilité est quelque chose comme rouler 6 6 fois de suite).
Maintenant, la partie de votre question sur la graine. Non, la graine ne peut pas déterminer la plage à partir de laquelle les nombres sont générés, elle détermine simplement le premier élément initial. Pensez à rand () comme une séquence de tous les nombres possibles dans la plage (permutation prédéterminée). La valeur de départ détermine où vous commencez à dessiner des nombres à partir de la séquence. C'est pourquoi si vous voulez un (pseudo) hasard, vous utilisez l'heure actuelle pour initialiser la séquence: vous ne vous souciez pas que la position à partir de laquelle vous partez ne soit pas uniformément répartie, tout ce qui compte c'est que vous ne partez jamais de la même position.
la source
l'utiliser
pow(2,rand())
vous donnera les réponses dans l'ordre de grandeur désirée !!la source
Si vous souhaitez utiliser des nombres aléatoires à partir d'un service en ligne, vous pouvez utiliser wget pour cela, vous voudrez peut-être voir que vous pouvez également utiliser des services comme random.org pour votre génération de nombres aléatoires, vous pouvez les attraper en utilisant wget, puis en lisant les nombres à partir de le fichier téléchargé
http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html
la source