1. Nombres pseudo-aléatoires

Parfois, un programmeur est confronté à des tâches apparemment simples : "sélectionner un film au hasard dans une certaine liste", "choisir un gagnant à la loterie", "mélanger la liste de lecture lorsque l'utilisateur secoue son smartphone", "choisir un numéro au hasard pour chiffrer un message" , etc. Dans chaque cas, le développeur pose une question logique : comment obtenir un nombre aléatoire ?

En fait, obtenir un nombre vraiment aléatoire est plutôt difficile à faire. En fait, c'est si difficile que des coprocesseurs mathématiques spéciaux sont intégrés à certains ordinateurs afin de générer des nombres qui satisfont à toutes les exigences d'un vrai hasard.

Les programmeurs ont trouvé leur propre solution : les nombres pseudo-aléatoires . Les nombres pseudo-aléatoires sont une sorte de séquence, dont les nombres semblent être aléatoires. Cependant, en effectuant une analyse minutieuse, un expert peut trouver certains modèles dans la séquence. De tels nombres ne conviennent pas pour chiffrer des documents secrets, mais ils suffisent pour simuler le lancer d'un dé dans un jeu.

Il existe de nombreux algorithmes pour générer une séquence de nombres pseudo-aléatoires. Presque tous génèrent le prochain numéro aléatoire basé sur le numéro précédent et quelques numéros d'assistance supplémentaires.

Par exemple, ce programme affichera 1000des nombres non répétitifs :

public class Main
{
   public static int a = 41;
   public static int c = 11119;
   public static int m = 11113;
   public static int seed = 1;

   public static int getNextRandom()
   {
     seed = (a * seed + c) % m;
     return seed;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 1000; i++)
     {
       System.out.println(getNextRandom());
     }
   }
}

Soit dit en passant, nous ne parlons pas ici de nombres pseudo-aléatoires. Nous parlons d'une séquence de nombres pseudo-aléatoires. En regardant un seul numéro, il est impossible de dire s'il est aléatoire ou non.

En effet, il existe différentes façons d'obtenir un nombre aléatoire :

public static int getRandomNumber()
{
   return 4; // Here's a random number (we got it by rolling a die)
}

2.Math.random()

En Java, la Mathclasse a une méthode spéciale qui renvoie un nombre aléatoire. Et comme vous pouvez le deviner, la méthode s'appelle random. En général, voici à quoi cela ressemble d'appeler cette méthode :

Math.random()

Cette méthode ne prend aucun paramètre et renvoie un nombre réel pseudo-aléatoire compris entre 0et 1. Le chiffre 1 lui-même n'est pas inclus dans la gamme.

Exemple:

Code Sortie console
public class Main
{
   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       System.out.println(Math.random());
     }
   }
}
0.9703753971734451
0.09979423801773157
0.994048474709053
0.2852203204171295
0.13551248551226025
0.3128547131272822
0.5342480554101412
0.6817369932044817
0.1840767788961758
0.06969563435451254

Mais que se passe-t-il si cette méthode n'est pas tout à fait ce dont vous avez besoin ? Supposons que vous vouliez écrire un programme qui simule le lancement d'un dé à six faces. Comment obtenez-vous des nombres entiers aléatoires dans la plage 1..6, au lieu de nombres réels dans la plage 0..1 ?

C'est en fait assez simple.

Tout d'abord, vous devez mapper la plage [0, 1)sur [0, 6). Pour cela, il suffit de multiplier le résultat renvoyé par random()par 6. Bien sûr, pour obtenir des nombres entiers, vous devez arrondir :

Code Sortie console
public class Main
{
   public static int getRandomDieNumber()
   {
      return (int) (Math.random() * 6);
   }

   public static void main(String[] args)
   {
      for (int i = 0; i < 10; i++)
      {
         int x = getRandomDieNumber();
         System.out.println(x);
      }
   }
}
5
2
3
3
2
4
1
1
5
0

La getRandomDieNumber()renvoie un entier aléatoire dans la plage 0..5incluse. Mais ce ne sera pas un numéro dans l'ensemble 1, 2, 3, 4, 5, 6. Ce sera un nombre dans l'ensemble 0, 1, 2, 3, 4, 5.

Si vous avez besoin de nombres dans l'ensemble 1, 2, 3, 4, 5, 6, ajoutez simplement un aux nombres aléatoires :

Code Sortie console
public class Main
{
   public static int getRandomDieNumber()
   {
      return (int) (Math.random() * 6) + 1;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       int x = getRandomDieNumber();
       System.out.println(x);
     }
   }
}
3
2
1
3
6
5
6
1
6
6

C'est parfait !



3. Randomclasse

Java a une classe spéciale Randomqui encapsule une séquence de nombres pseudo-aléatoires. Vous pouvez créer plusieurs objets de la Randomclasse. Chacun de ces objets générera sa propre séquence de nombres pseudo-aléatoires.

C'est une classe super intéressante avec beaucoup de méthodes intéressantes. Commençons par le plus simple.

double nextDouble()

Cette méthode renvoie un nombre réel aléatoire dans la plage 0.0- 1.0. C'est très similaire à la Math.random()méthode. Et ce n'est pas étonnant, puisque la Math.random()méthode appelle simplement la nextDouble()méthode sur un Randomobjet.

float nextFloat()

Cette méthode est très similaire à la nextDouble()méthode , mais le nombre aléatoire renvoyé est un float. Il se situe également dans la gamme 0.0- 1.0. Et, comme toujours en Java, la plage n'inclut pas le nombre 1.0lui-même.

Random r = new Random();
float f = r.nextFloat();

int nextInt(int max)

Cette méthode renvoie un entier aléatoire dans la plage [0, max). 0est inclus dans la gamme, mais maxne l'est pas.

En d'autres termes, si vous souhaitez obtenir un nombre aléatoire dans l'ensemble 1, 2, 3, 4, 5, 6, vous devez en ajouter un au nombre aléatoire renvoyé :

Random r = new Random();
int x = r.nextInt(6) + 1;

int nextInt()

Cette méthode est similaire à la précédente, mais elle ne prend aucun paramètre. Alors, quelle est la plage de ses valeurs de retour ? De -2 billionà +2 billion.

Eh bien, pour être précis, de -2147483648à +2147483647.

long nextLong()

Cette méthode est similaire à la nextInt()méthode , mais la valeur de retour se situera quelque part dans toute la plage possible de longs.

boolean nextBoolean()

Cette méthode retourne une booleanvaleur aléatoire : falseou true. C'est très pratique lorsque vous avez besoin d'obtenir une longue séquence de valeurs booléennes aléatoires.

void nextBytes(byte[] data)

Cette méthode ne renvoie rien (puisque le type de retour est void). Au lieu de cela, il remplit le tableau passé avec des valeurs aléatoires. Ceci est très pratique lorsque vous avez besoin d'un grand tampon rempli de données aléatoires.

double nextGaussian()

Cette méthode renvoie un nombre réel aléatoire dans la plage 0.0- 1.0. Cependant, les chiffres ne sont pas uniformément répartis dans cette plage. Au lieu de cela, ils suivent une distribution normale .

Les valeurs proches du milieu de la plage ( 0.5) apparaîtront plus souvent que les valeurs aux extrémités de la plage.

Classe aléatoire

Dans notre cas, le pic de la distribution de valeur sera à0.5