31 votes

Rand () retournera-t-il parfois la même chose consécutivement?

Je suis juste curieux, un programme mono-thread peut-il jamais obtenir la même valeur de retour pour deux appels consécutifs à rand() ?

Alors, cette affirmation va-t-elle jamais tirer?

 assert(rand() != rand());
 

46voto

nos Points 102226

Si nous pouvons trouver un exemple où il n', la réponse à votre question est "oui".

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  unsigned int i;
  for(i = 0; ; i++) {
    int r = rand();
    if (r == rand()) {
        printf("Oops. rand() = %d; i = %d\n", r, i);
        break;
    }
  }
  return 0;
}

imprime Oops. rand() = 3482; i = 32187 sur Windows avec Visual Studio 2010.

EDIT: Utiliser la version ci-dessous afin de détecter toutes les séquences où 2 consécutifs rand() appelle retourner la même valeur. C précise seulement que le rand() doit retourner "pseudo-aléatoire de nombres entiers dans l'intervalle de 0 à RAND_MAX" et RAND_MAX doit être d'au moins 32767. Il n'y a pas de contraintes sur la qualité du GÉNÉRATEUR, ou c'est la mise en œuvre, ou d'autres détails tels que si 2 consécutifs rand() appelle peut retourner la même valeur.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  unsigned int i;
  int r1 = rand();
  int r2 = rand();
  for(i = 0; ; i++) {
    if (r1 == r2) {
        printf("Oops. rand() = %d; i = %d\n", r1, i);
    }
    r1 = r2;
    r2 = rand();
  }
  return 0;
}

30voto

Gohan Points 899

J'ai fait mes recherches

découvert que mon compilateur(msvc10)'s rand mise en œuvre n'utilisez générateur Linéaire à congruence à l'instar d'autres compilateur c/c++

Générateur linéaire à congruence

Générateur linéaire à congruence utiliser la récurrence de la méthode.

use the

ptd->_holdrand(n) ne sera jamais égal à ptd->_holdrand(n+1), mais le mod résultat sera égal.

msvc mise en œuvre

@nsa montre le résultat

return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff );

ptd->_holdrand = 2375716238;
return 3482; (2375716238 >> 16) % 32768
ptd->_holdrand = 228240921;
return 3482; (228240921 >> 16) % 32768

réponse finale est le rand() retourne la même valeur à deux reprises, à certains moments, comme mon instinct.

8voto

dan04 Points 33306

Un idéalement aléatoire rand() de la fonction, si elle est appelée deux fois, serait de retourner le même résultat à chaque fois, avec une probabilité d' 1.0 / RAND_MAX.

Mais rand() n'est pas un vrai générateur de nombre aléatoire. C'est un générateur de nombres pseudo-aléatoires (PRNG), généralement de la congruence linéaire de type.

L' état interne du GÉNÉRATEUR ne doit pas être répétées sur les appels consécutifs; si elle le faisait, rand() serait restée bloquée sur le même nombre pour toujours. Cela peut arriver avec des mal-conçu des algorithmes tels que la moyenne méthode des moindres carrés.

Cependant, certains (mais pas tous) PRNG implémentations ont plus de bits dans leur état interne que ce qu'ils ont dans leur sortie. Par exemple, java.util.Random utilise un 48 bits interne de l'état, mais seulement les plus importants de 32 bits en sortie. Dans ce cas, c'est (au moins théoriquement) possible d'obtenir le même résultat deux fois de suite sans avoir le même état interne.

6voto

gnasher729 Points 5011

Un bon générateur de nombres aléatoires devrait parfois renvoyer la même valeur deux fois de suite. Supposons qu'il retourne des entiers positifs 0 <= r <2 ^ 31. La probabilité que deux nombres consécutifs soient identiques serait d'environ un sur deux milliards pour un générateur de nombre aléatoire parfait. La probabilité de ne pas obtenir deux numéros consécutifs identiques pour 100 milliards d'appels est d'environ un sur 10 ^ 15.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X