Go Down

Topic: Un cas particulier ou random(max) n'est pas équitable (Read 75 times) previous topic - next topic

Bonjour,

Voici un programme qui ne sert à rien, qui montre une faille de random(max).

Je prends deux intervalles contenant le même nombre de valeurs [0, TAILLE_INTERVALLE[ et [TAILLE_INTERVALLE, 2*TAILLE_INTERVALLE[ et je demande à random de me fournir un entier au hasard sur ces deux intervalles. Si par exemple je fais random(200), j'ai autant de chances d'avoir un nombre entre 0 et 99 qu'un nombre entre 100 et 199.
Et bien ce raisonnement ne fonctionne pas toujours. Pour TAILLE_INTERVALLE valant 0x2A000000, j'ai quasiment deux fois plus de chances d'avoir un nombre dans la première moitié.
 
Voici un petit programme de test:
Code: [Select]

/*  Ce programme permet d'afficher le nombre de fois que le générateur pseudo
 *  aléatoire random fournit une valeur dans un intervalle ou dans un autre
 */
 
#define TAILLE_INTERVALLE 0x2A000000 // c'est moi qui choisit

void setup()
{
  Serial.begin(115200);
}

long intervalle1, intervalle2; // Compte le nombre de fois qu'on est dans le premier ou le deuxième intervalle

long valeurAleatoire;

void loop()
{
  valeurAleatoire=random(2*TAILLE_INTERVALLE); // Nouvelle valeur, faut mettre un nombre entre 0 et 7FFFFFFF (long)
  if (valeurAleatoire<TAILLE_INTERVALLE) intervalle1++; // La valeur est dans le premier intervalle
  else intervalle2++;  // La valeur est dans le deuxième intervalle
  if ((intervalle1+intervalle2) % 10000 == 0) // Affichage du résultat de temps en temps
  {
    Serial.print("Sur ");
    Serial.print(intervalle1+intervalle2);
    Serial.print(" valeurs, on est à ");
    Serial.print(intervalle1*100/(intervalle1+intervalle2));
    Serial.println("% de chances dans le premier intrvalle");
  }
  if (intervalle1+intervalle2 > 40000000) while(1); // Arrêt si le calcul déborde
}


Il va afficher 66% très rapidement. Avec une autre taille d'intervalle, on se rapproche des 50% espérés. J'ai choisi presque le pire des cas! Rassurez vous, random(max) fonctionne à peu près correctement quand Max est loin de 0x2A000000 ce qui est généralement le cas.

Tout cela prouve en tout cas qu'il y en a qui n'ont rien d'autre chose à faire que de chercher des cas où random(max) ne fonctionne pas. Vive le confinement!

Go Up