Comment générer des entiers aléatoires dans une plage spécifique en Java?


Comment générer une valeur aléatoire int dans une plage spécifique?

J'ai essayé ce qui suit, mais ceux-ci ne fonctionnent pas:

Tentative 1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.

Tentative 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.
Author: Steve Chambers, 2008-12-12

30 answers

Dans Java 1.7 ou version ultérieure , la façon standard de le faire est la suivante:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

Voir le JavaDoc pertinent. Cette approche a l'avantage de ne pas avoir besoin d'initialiser explicitement un java.util.Instance aléatoire , qui peut être une source de confusion et d'erreur si elle est utilisée de manière inappropriée.

Cependant, inversement, il n'y a aucun moyen de définir explicitement la graine, il peut donc être difficile de reproduire les résultats dans des situations où cela est utile, comme les tests ou l'enregistrement états de jeu ou similaires. Dans ces situations, la technique pré-Java 1.7 illustrée ci-dessous peut être utilisée.

Avant Java 1.7 , la façon standard de le faire est la suivante:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

Voir le JavaDoc pertinent. En pratique, le java.util.La classe Random est souvent préférable à java.lang.Mathématique.random () .

En particulier, il n'est pas nécessaire de réinventer la roue de génération d'entiers aléatoires lorsqu'il existe une API simple dans la bibliothèque standard pour accomplir la tâche.

 3312
Author: Greg Case, 2018-01-04 07:02:27

Notez que cette approche est plus biaisé et moins efficace qu'un nextInt approche, https://stackoverflow.com/a/738651/360211

Un modèle standard pour accomplir ceci est:

Min + (int)(Math.random() * ((Max - Min) + 1))

Le Java Bibliothèque de mathématiques fonction Math.random () génère une valeur double dans la plage [0,1). Avis cette plage ne comprend pas le 1.

Pour obtenir d'abord une plage de valeurs spécifique, vous devez multiplier par l'amplitude de la plage de valeurs que vous voulez couvrir.

Math.random() * ( Max - Min )

Cela renvoie une valeur dans la plage [0,Max-Min), où 'Max-Min' n'est pas inclus.

Par exemple, si vous voulez [5,10), vous devez couvrir cinq valeurs entières afin d'utiliser

Math.random() * 5

Cela renverrait une valeur dans la plage [0,5), où 5 n'est pas inclus.

Vous devez maintenant déplacer cette plage vers la plage que vous ciblez. Vous le faites en ajoutant la valeur Min.

Min + (Math.random() * (Max - Min))

Vous obtiendrez maintenant une valeur dans la plage [Min,Max). À la suite de notre exemple, cela signifie [5,10):

5 + (Math.random() * (10 - 5))

Mais, cela n'inclut toujours pas Max et vous obtenez une double valeur. Afin d'obtenir la valeur Max incluse, vous devez ajouter 1 à votre paramètre de plage (Max - Min), puis tronquer la partie décimale en la convertissant en int. Ceci est accompli par:

Min + (int)(Math.random() * ((Max - Min) + 1))

Et là vous l'avez. Une valeur entière aléatoire dans l'intervalle [Min,Max], ou par l'exemple [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))
 1343
Author: TJ_Fischer, 2018-07-24 13:19:30

Utilisation:

Random ran = new Random();
int x = ran.nextInt(6) + 5;

Integer x est maintenant le nombre aléatoire qui a un résultat possible de 5-10.

 314
Author: Azeem, 2018-04-23 05:19:53

Utilisation:

minimum + rn.nextInt(maxValue - minvalue + 1)
 126
Author: krosenvold, 2014-06-22 22:22:52

Avec java-8, ils ont introduit la méthode ints(int randomNumberOrigin, int randomNumberBound) dans le Random classe.

Par exemple, si vous voulez générer cinq entiers aléatoires (ou un seul) dans la plage [0, 10], faites simplement:

Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();

Le premier paramètre indique juste la taille du IntStream généré (qui est la méthode surchargée de celle qui produit un IntStream illimité).

Si vous devez effectuer plusieurs appels distincts, vous pouvez créer un itérateur primitif infini à partir du flux:

public final class IntRandomNumberGenerator {

    private PrimitiveIterator.OfInt randomIterator;

    /**
     * Initialize a new random number generator that generates
     * random numbers in the range [min, max]
     * @param min - the min value (inclusive)
     * @param max - the max value (inclusive)
     */
    public IntRandomNumberGenerator(int min, int max) {
        randomIterator = new Random().ints(min, max + 1).iterator();
    }

    /**
     * Returns a random number in the range (min, max)
     * @return a random number in the range (min, max)
     */
    public int nextInt() {
        return randomIterator.nextInt();
    }
}

Vous pouvez également le faire pour les valeurs double et long.

J'espère que ça aide! :)

 102
Author: Alexis C., 2017-10-04 11:39:56

, Vous pouvez modifier votre deuxième exemple de code:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
 91
Author: Bill the Lizard, 2008-12-12 18:31:28

Juste une petite modification de votre première solution suffirait.

Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);

Voir plus ici pour la mise en œuvre de Random

 90
Author: hexabunny, 2018-04-20 16:51:23

ThreadLocalRandom équivalent de la classe java.util.Aléatoire pour l'environnement multithread. La génération d'un nombre aléatoire est effectuée localement dans chacun des threads. Nous avons donc une meilleure performance en réduisant les conflits.

int rand = ThreadLocalRandom.current().nextInt(x,y);

X,y - intervalles par exemple (1,10)

 57
Author: andrew, 2016-04-21 06:03:42

La classe Math.Randomdans Java est basée sur 0. Donc, si vous écrivez quelque chose comme ceci:

Random rand = new Random();
int x = rand.nextInt(10);

x sera compris entre 0-9 inclus.

Donc, étant donné le tableau suivant de 25 articles, le code pour générer un nombre aléatoire entre 0 (la base de la matrice) et array.length serait:

String[] i = new String[25];
Random rand = new Random();
int index = 0;

index = rand.nextInt( i.length );

Puisque i.length retournera 25, le nextInt( i.length ) retournera un nombre entre la plage de 0-24. L'autre option va avec Math.Random qui fonctionne dans le même façon.

index = (int) Math.floor(Math.random() * i.length);

, Pour une meilleure compréhension, découvrez post sur le forum Intervalles Aléatoires (archive.org).

 54
Author: Matt R, 2018-04-23 05:19:23

Pardonnez - moi d'être fastidieux, mais la solution proposée par la majorité, c'est-à-dire min + rng.nextInt(max - min + 1)), semble périlleuse du fait que:

  • rng.nextInt(n) ne peut pas atteindre Integer.MAX_VALUE.
  • (max - min) peut provoquer un débordement lorsque min est négatif.

Une solution infaillible renverrait des résultats corrects pour tout min <= max dans [Integer.MIN_VALUE, Integer.MAX_VALUE]. Considérons l'implémentation naïve suivante:

int nextIntInRange(int min, int max, Random rng) {
   if (min > max) {
      throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
   }
   int diff = max - min;
   if (diff >= 0 && diff != Integer.MAX_VALUE) {
      return (min + rng.nextInt(diff + 1));
   }
   int i;
   do {
      i = rng.nextInt();
   } while (i < min || i > max);
   return i;
}

Bien qu'inefficace, notez que la probabilité de succès dans la boucle while toujours être 50% ou plus.

 44
Author: Joel Sjöstrand, 2018-04-23 05:21:33

Je me demande si l'une des méthodes de génération de nombres aléatoires fournies par une bibliothèque Apache Commons Math conviendrait à la facture.

Par exemple: RandomDataGenerator.nextInt ou RandomDataGenerator.nextLong

 26
Author: Chinnery, 2016-11-16 12:08:17

Prenons un exemple.

Supposons que je souhaite générer un nombre entre 5-10:

int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);

Comprenons ceci ...

Initialisez max avec la valeur la plus élevée et min avec la valeur la plus basse.

Maintenant, nous devons déterminer combien de valeurs possibles peuvent être obtenues. Pour cet exemple, ce serait:

5, 6, 7, 8, 9, 10

Donc, le nombre de ceci serait max-min + 1.

C'est-à-dire. 10 - 5 + 1 = 6

, Le nombre aléatoire génère un nombre entre 0-5.

C'est-à-dire. 0, 1, 2, 3, 4, 5

Ajouter la valeurmin au nombre aléatoire produirait:

5, 6, 7, 8, 9, 10

On obtient donc la plage souhaitée.

 25
Author: Sunil Chawla, 2018-04-26 20:14:06
 rand.nextInt((max+1) - min) + min;
 22
Author: Michael Myers, 2017-12-20 19:34:30

Voici une classe utile pour générer random ints dans une plage avec n'importe quelle combinaison de limites inclusives/exclusives:

import java.util.Random;

public class RandomRange extends Random {
    public int nextIncInc(int min, int max) {
        return nextInt(max - min + 1) + min;
    }

    public int nextExcInc(int min, int max) {
        return nextInt(max - min) + 1 + min;
    }

    public int nextExcExc(int min, int max) {
        return nextInt(max - min - 1) + 1 + min;
    }

    public int nextIncExc(int min, int max) {
        return nextInt(max - min) + min;
    }
}
 18
Author: Garrett Hall, 2012-02-15 16:19:03

Générez un nombre aléatoire pour la différence de min et max en utilisant la méthode nextint (n) {[3] } puis ajoutez le nombre min au résultat:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
 18
Author: gifpif, 2016-07-06 19:23:24

En cas de lancer un dé, ce serait un nombre aléatoire entre 1 et 6 (pas 0 à 6), donc:

face = 1 + randomNumbers.nextInt(6);
 17
Author: sam, 2016-04-21 06:01:47

À partir de Java 7, vous ne devez plus utiliser Random. Pour la plupart des utilisations, le le générateur de nombres aléatoires de choix est maintenant ThreadLocalRandom.

Pour la fourche rejoindre piscines et parallèle flux, utilisation SplittableRandom.

Joshua Bloch. Java efficace. Troisième Édition.

À partir de Java 8

Pour les pools de jointure fork et les flux parallèles, utilisez {[5] } qui est généralement plus rapide, a une meilleure indépendance statistique et des propriétés d'uniformité dans comparaison avec Random.

Pour générer un int aléatoire dans la plage [0, 1_000]:

int n = new SplittableRandom().nextInt(0, 1_001);

Pour générer un tableau aléatoire int[100] de valeurs dans la plage [0, 1_000]:

int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();

Pour renvoyer un flux de valeurs aléatoires:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
 17
Author: Oleksandr, 2018-05-20 19:07:45
int random = minimum + Double.valueOf(Math.random()*(maximum-minimun)).intValue();

Ou jetez un oeil à RandomUtils de Apache Commons.

 16
Author: user2427, 2014-06-22 22:23:28

Cette méthode peut être pratique à utiliser:

Cette méthode retourne un nombre aléatoire entre la condition valeurs min et max:

public static int getRandomNumberBetween(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt(max - min) + min;
    if (randomNumber == min) {
        // Since the random number is between the min and max values, simply add 1
        return min + 1;
    } else {
        return randomNumber;
    }
}

Et cette méthode renverra un nombre aléatoirede la valeur min et max fournie (donc le nombre généré pourrait également être le nombre min ou max):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}
 16
Author: Luke Taylor, 2017-12-20 19:37:20

Lorsque vous avez besoin de beaucoup de nombres aléatoires, je ne recommande pas la classe aléatoire dans l'API. Il a juste une trop petite période. Essayez plutôt le Mersenne twister. Il existe une implémentation Java.

 15
Author: raupach, 2013-08-01 18:02:34
public static Random RANDOM = new Random(System.nanoTime());

public static final float random(final float pMin, final float pMax) {
    return pMin + RANDOM.nextFloat() * (pMax - pMin);
}
 15
Author: AZ_, 2013-08-01 18:25:39

J'ai trouvé cet exemple Générer des nombres aléatoires :


Cet exemple génère des entiers aléatoires dans une plage spécifique.

import java.util.Random;

/** Generate random integers in a certain range. */
public final class RandomRange {

  public static final void main(String... aArgs){
    log("Generating random integers in the range 1..10.");

    int START = 1;
    int END = 10;
    Random random = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      showRandomInteger(START, END, random);
    }

    log("Done.");
  }

  private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
    if ( aStart > aEnd ) {
      throw new IllegalArgumentException("Start cannot exceed End.");
    }
    //get the range, casting to long to avoid overflow problems
    long range = (long)aEnd - (long)aStart + 1;
    // compute a fraction of the range, 0 <= frac < range
    long fraction = (long)(range * aRandom.nextDouble());
    int randomNumber =  (int)(fraction + aStart);    
    log("Generated : " + randomNumber);
  }

  private static void log(String aMessage){
    System.out.println(aMessage);
  }
} 

Un exemple d'exécution de cette classe:

Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.
 15
Author: Hospes, 2017-12-20 19:35:57

Vous pouvez y parvenir de manière concise en Java 8:

Random random = new Random();

int max = 10;
int min = 5;
int totalNumber = 10;

IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);
 15
Author: Mulalo Madida, 2018-04-26 20:08:56

Voici un exemple simple qui montre comment générer un nombre aléatoire à partir de la plage [min, max] fermée, tandis que min <= max is true

Vous pouvez le réutiliser en tant que champ dans la classe hole, en ayant également toutes les méthodes Random.class au même endroit

Exemple de Résultats:

RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert

Sources:

import junit.framework.Assert;
import java.util.Random;

public class RandomUtils extends Random {

    /**
     * @param min generated value. Can't be > then max
     * @param max generated value
     * @return values in closed range [min, max].
     */
    public int nextInt(int min, int max) {
        Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
        if (min == max) {
            return max;
        }

        return nextInt(max - min + 1) + min;
    }
}
 14
Author: Yakiv Mospan, 2014-11-28 00:58:54

Utilisez simplement la classe Random :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
 14
Author: Prof Mo, 2016-04-21 06:04:49

Une autre option consiste simplement à utiliser Apache Commons :

import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;

public void method() {
    RandomData randomData = new RandomDataImpl();
    int number = randomData.nextInt(5, 10);
    // ...
 }
 14
Author: gerardw, 2018-04-23 05:22:28

Si vous voulez essayer de répondre avec le plus de votes ci-dessus, vous pouvez simplement utiliser ce code:

public class Randomizer
{
    public static int generate(int min,int max)
    {
        return min + (int)(Math.random() * ((max - min) + 1));
    }

    public static void main(String[] args)
    {
        System.out.println(Randomizer.generate(0,10));
    }
}

C'est juste propre et simple.

 11
Author: Abel Callejo, 2014-06-22 22:26:02
private static Random random = new Random();    

public static int getRandomInt(int min, int max){
  return random.nextInt(max - min + 1) + min;
}

OU

public static int getRandomInt(Random random, int min, int max)
{
  return random.nextInt(max - min + 1) + min;
}
 11
Author: Muhammad Aamir Talib, 2016-04-21 06:05:53

Il est préférable d'utiliser SecureRandom plutôt que simplement aléatoire.

public static int generateRandomInteger(int min, int max) {
    SecureRandom rand = new SecureRandom();
    rand.setSeed(new Date().getTime());
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}
 11
Author: grep, 2016-07-06 19:19:36
rand.nextInt((max+1) - min) + min;

Cela fonctionne bien.

 10
Author: ganesh, 2016-04-21 06:01:59