Comment puis-je réduire les numéros de rand()?
Le code suivant renvoie un nombre aléatoire à chaque seconde:
int main ()
{
srand(time(NULL)); //Seeds number generator with execution time.
while (true)
{
int rawRand = rand();
std::cout << rawRand << std::endl;
sleep(1);
}
}
Comment pourrais-je taille ces chiffres vers le bas de sorte qu'ils sont toujours dans la gamme de 0 à 100?
- int GetRandom() { return 59; /*A parfaitement choisi au hasard le numéro de*/}
- Serait-ce un xkcd référence vois-je? 😛
- naah, vu dans beaucoup trop d'endroits à-dire la source exacte, et être capable de s'abstenir de m'écrire que.
- le temps de sommeil est exprimé en millisecondes, de l'utilisation de sleep(1000) pour dormir pendant une seconde.
- Pas dans la mise en œuvre que j'utilise, il n'est pas. Comment étrange.
- ses aussi un de Dilbert de référence
- Pourriez-vous s'il vous plaît activer la accepté de répondre à celui-ci?
- Génial, merci beaucoup! Je suis sûr que Justin sauront l'apprécier. 🙂
Vous devez vous connecter pour publier un commentaire.
Si vous êtes à l'aide de C++ et que vous êtes inquiet au sujet de la bonne distribution, vous pouvez utiliser
TR1de C++11<random>
.random_device
ne fonctionne pas toujours: Il retuns 34992116121 à chaque fois, dans mon cas.std::random_device
mais rien trouvé, désolé.int[mt19937::state_size]
, à l'aide degenerate_n
avec unrandom_device
de le remplir avec de l'aléatoire, de faire unseed_seq
à partir de ce tableau, puis la construction de la mersenne twister moteur de cetteseed_seq
.Tous les exemples affichés jusqu'à présent réellement donner mal distribués résultats. Exécuter le code souvent et créer des statistiques pour voir comment les valeurs deviennent asymétriques.
Une meilleure façon de générer un réel uniforme de nombres aléatoires de distribution dans tout l'intervalle [0, N] est le suivant (en supposant que
rand
effectivement suit une distribution uniforme, ce qui est loin d'être évident):Bien sûr, cette méthode est lente, mais elle ne produire une bonne distribution. Un peu plus intelligente façon de le faire est de trouver le plus grand multiple de N qui est plus petit que
RAND_MAX
et en utilisant ce que la limite supérieure. Après cela, on peut prendre en toute sécurité leresult % (N + 1)
.Pour une explication pourquoi le naïf module méthode est mauvaise et pourquoi le ci-dessus est mieux, reportez-vous à la Julienne de l'excellent article sur à l'aide de
rand
.java.util.Random#nextInt(int)
par exemple.while(result > (RAND_MAX - RAND_MAX % N))
et en divisant parRAND_MAX/N
. Vous jetez beaucoup moins de numéros pour les petits N, mais de garder la distribution uniforme.RAND_MAX/N
. Juste à l'aide de% (N+1)
doit sûrement être bien?rand
" (eternallyconfuzzled dot com) est cassé et maintenant les points à un spam de blog à propos de l'achat de vues sur Youtube.Voir (pour plus de détails):
rand - C++ de Référence
D'autres ont également souligné que cela ne va pas vous donner la meilleure répartition des nombres aléatoires possibles. Si ce genre de chose qui est important dans votre code, vous devrez faire:
MODIFIER
Trois ans, je suis en train de faire un montage. Comme d'autres l'ont mentionné,
rand()
a beaucoup de questions. Évidemment, je ne peux pas recommander son utilisation lorsqu'il y a de meilleures alternatives à l'avenir. Vous pouvez lire tous les détails et les recommandations ici:rand() Considéré comme Nocif | GoingNative 2013
java.util.Random#nextInt(int)
.rawRand
fera preuve d'une certaine partialité si vous utilisez cette technique (en supposant que 101 n'est pas un facteur deRAND_MAX
).rand()
a RAND_MAX+1 valeurs; sauf si c'est un multiple de 101 (ce qui n'est probablement pas), il n'existe aucun moyen de les attribuer à 101 seaux sans que l'un d'entre eux étant plus grand.Vous pouvez faire
Pour les personnes downvoting; remarque une minute après que cela a été posté j'ai laissé le commentaire:
Avec 64-bit ints et à l'aide de 100 numéros de la sortie, les chiffres de 0 à 16 sont représentés avec 1.00000000000000000455 % des effectifs (soit une précision relative à identiquement distribuées de 1% par environ 10-18), tandis que le nombre 17-99 sont représentés avec 0.99999999999999999913 % des effectifs. Oui, parfaitement distribuées, mais une très bonne approximation pour les petites amplitudes.
Noter également, d'où l'OP demander identiquement distribuées numéros? Pour tous nous savons que ces sommes soient utilisées à des fins où un petits écarts n'a pas d'importance (p. ex., rien d'autre que la cryptographie -- et si ils sont en utilisant les numéros de cryptographie à cette question est beaucoup trop naïf pour eux d'écrire leur propre cryptographie).
MODIFIER - Pour les personnes qui sont véritablement intéressés à avoir une distribution uniforme de nombres aléatoires le code suivant fonctionne. Remarque ce n'est pas nécessairement la solution optimale qu'avec la version 64 bits aléatoires entiers, il faudra deux appels de
rand()
une fois tous les 10^18 appels.Voir
man 3 rand
-- vous avez besoin à l'échelle en divisant parRAND_MAX
pour obtenir l'intervalle [0, 1], après quoi vous pouvez multiplier par 100 pour votre fourchette cible.rand()
est de commencer. Il est généralement assez nul, si.RAND_MAX
plutôt que%
module.rand()
est qu'il est permis à un atroce PRNG. Toute utilisation, il est suspect si bon nombres aléatoires sont nécessaires, mais certains sont encore plus suspect que les autres.Pour la gamme min à max (inclus), utilisation:
int result = rand() % (max - min + 1) + min;
Combien de temps une réponse vous souhaitez.
le plus simple est de convertir en utilisant le reste quand il est divisé en 101:
Un semipurist serait le redimensionner à l'aide de doubles:
Et un puriste dirais que rand ne pas produire des nombres aléatoires.
Pour votre info, la qualité de nombres aléatoires est mesurée par la prise d'une séquence de nombres et calcul de la probabilité mathématique que la source de cette séquence est aléatoire. Le simple hack en utilisant le reste est un très mauvais choix si vous êtes après l'aléatoire.
Certaines personnes ont affiché le code suivant comme exemple:
C'est une défaillance des moyens de résoudre le problème, à la fois comme rand() et RAND_MAX sont des nombres entiers. En C++, il en résulte partie intégrante de la division, qui va tronquer les résultats des points décimaux. Comme RAND_MAX >= rand(), le résultat de cette opération est soit 1, soit 0, ce qui signifie rawRand ne peut être que 0 ou 100. Une bonne façon de le faire serait le suivant:
Puisque l'un des opérandes est maintenant un double, floating point de la division est utilisé, qui doit retourner une valeur entre 0 et 1.
rawRand == 100
est très peu probable puisque seulementRAND_MAX
"produit" il.rawRand % 101 donnerait [0-100], inclusivement.