Un cas particulier ou random(max) n'est pas équitable

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:

/*  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!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.