Hoe genereer ik willekeurige gehele getallen binnen een specifiek bereik in Java?

Hoe genereer ik een willekeurige int waarde in een specifiek bereik?

Ik heb het volgende geprobeerd, maar dat werkt niet:

Poging 1:

randomNum = minimum + (int)(Math.random() * maximum);

Bug: randomNum kan groter zijn dan maximum.

Poging 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;

Bug: randomNum kan kleiner zijn dan minimum.


Antwoord 1, autoriteit 100%

In Java 1.7 of hoger is de standaardmanier om dit te doen als volgt:

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);

Zie de relevante JavaDoc. Deze aanpak heeft het voordeel dat het niet expliciet nodig is om een ​​java.util.Random instantie, die bij onjuist gebruik een bron van verwarring en fouten kan zijn.

Omgekeerd is er echter geen manier om de seed expliciet in te stellen, dus het kan moeilijk zijn om resultaten te reproduceren in situaties waarin dat nuttig is, zoals het testen of opslaan van gamestatussen of iets dergelijks. In die situaties kan de hieronder getoonde pre-Java 1.7-techniek worden gebruikt.

Vóór Java 1.7 is de standaardmanier om dit te doen als volgt:

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;
}

Zie de relevante JavaDoc. In de praktijk is de java De klasse .util.Random heeft vaak de voorkeur boven java.lang.Math.random().

In het bijzonder is het niet nodig om het wiel voor het genereren van willekeurige gehele getallen opnieuw uit te vinden als er een eenvoudige API in de standaardbibliotheek is om de taak te volbrengen.


Antwoord 2, autoriteit 36%

Merk op dat deze benadering meer bevooroordeeld en minder efficiënt is dan een nextInt-benadering, https://stackoverflow .com/a/738651/360211

Een standaardpatroon om dit te bereiken is:

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

De Java Wiskundige bibliotheekfunctie Math.random() genereert een dubbele waarde in het bereik [0,1). Merk op dat dit bereik niet de 1 bevat.

Om eerst een specifiek waardenbereik te krijgen, moet u vermenigvuldigen met de grootte van het waardenbereik dat u wilt bestrijken.

Math.random() * ( Max - Min )

Dit retourneert een waarde in het bereik [0,Max-Min), waarbij ‘Max-Min’ niet is opgenomen.

Als u bijvoorbeeld [5,10) wilt, moet u vijf gehele getallen afdekken, zodat u

Math.random() * 5

Dit zou een waarde in het bereik [0,5) opleveren, waarbij 5 niet is inbegrepen.

Nu moet u dit bereik verschuiven naar het bereik waarop u zich richt. Dit doe je door de Min-waarde toe te voegen.

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

Je krijgt nu een waarde in het bereik [Min,Max). In navolging van ons voorbeeld betekent dat [5,10):

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

Maar dit is nog steeds niet inclusief Max en je krijgt een dubbele waarde. Om de waarde Max op te nemen, moet u 1 toevoegen aan uw bereikparameter (max - min) en vervolgens het decimale deel afkappen door naar een int te casten. Dit wordt bereikt via:

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

En daar heb je het. Een willekeurig geheel getal in het bereik [Min,Max], of volgens het voorbeeld [5,10]:

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

Antwoord 3, autoriteit 10%

Gebruik:

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

Het gehele getal x is nu het willekeurige getal met een mogelijke uitkomst van 5-10.


Antwoord 4, autoriteit 4%

Gebruik:

minimum + rn.nextInt(maxValue - minvalue + 1)

Antwoord 5, autoriteit 4%

Met ze introduceerden de methode ints(int randomNumberOrigin, int randomNumberBound) in de Random klasse.

Als u bijvoorbeeld vijf willekeurige gehele getallen (of één enkele) in het bereik [0, 10] wilt genereren, doet u het volgende:

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

De eerste parameter geeft alleen de grootte aan van de gegenereerde IntStream (wat de overbelaste methode is van degene die een onbeperkte IntStream produceert).

Als u meerdere afzonderlijke oproepen moet doen, kunt u een oneindige primitieve iterator van de stream maken:

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();
    }
}

Je kunt het ook doen voor double en long waarden. Ik hoop dat het helpt! 🙂


Antwoord 6, autoriteit 3%

U kunt uw tweede codevoorbeeld bewerken om:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;

Antwoord 7, autoriteit 3%

Een kleine wijziging van uw eerste oplossing zou voldoende zijn.

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

Zie hier meer voor de implementatie van Random


Antwoord 8, autoriteit 2%

ThreadLocalRandom equivalent van klasse java.util.Random voor multithreaded-omgevingen. Het genereren van een willekeurig getal wordt lokaal in elk van de threads uitgevoerd. We presteren dus beter door de conflicten te verminderen.

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

x,y – intervallen b.v. (1,10)


Antwoord 9, autoriteit 2%

De klasse Math.Random in Java is gebaseerd op 0. Dus, als je zoiets schrijft:

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

x ligt tussen 0-9 inclusief.

Dus, gegeven de volgende array van 25 items, de code om een ​​willekeurig getal te genereren tussen 0 (de basis van de array) en array.length zou zijn:

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

Aangezien i.length 25 retourneert, retourneert de nextInt( i.length ) een getal tussen het bereik van 0-24. De andere optie gaat met Math.Random die op dezelfde manier werkt.

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

Voor een beter begrip, bekijk de forumpost Willekeurige intervallen (archive.org).


Antwoord 10

Het kan gedaan worden door simpelweg de volgende instructie uit te voeren:

Randomizer.generate(0,10); //min of zero, max of ten

Hieronder staat de broncode

Randomizer.java

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

Het is gewoon schoon en eenvoudig.


Antwoord 11

Vergeef me dat ik kieskeurig ben, maar de oplossing die door de meerderheid wordt voorgesteld, namelijk min + rng.nextInt(max - min + 1)), lijkt gevaarlijk vanwege het feit dat:

  • rng.nextInt(n) kan Integer.MAX_VALUE niet bereiken.
  • (max - min) kan overflow veroorzaken wanneer min negatief is.

Een onfeilbare oplossing zou correcte resultaten opleveren voor elke min <= max binnen [Integer.MIN_VALUE, Integer.MAX_VALUE]. Overweeg de volgende naïeve implementatie:

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;
}

Hoewel inefficiënt, houd er rekening mee dat de kans op succes in de while-lus altijd 50% of hoger zal zijn.


Antwoord 12

Ik vraag me af of een van de methoden voor het genereren van willekeurige getallen die door een Apache Commons Math bibliotheek zou passen.

Bijvoorbeeld: RandomDataGenerator.nextInt of RandomDataGenerator.nextLong


Antwoord 13

Ik gebruik dit:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max + 1 - min)) + min;
 }

Je kunt het naar een geheel getal casten als je wilt.


Antwoord 14

Laten we een voorbeeld nemen.

Stel dat ik een getal tussen 5-10 wil genereren:

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);

Laat ons dit begrijpen

Initialiseer max met de hoogste waarde en min met de laagste waarde.

Nu moeten we bepalen hoeveel mogelijke waarden kunnen worden verkregen. Voor dit voorbeeld zou het zijn:

5, 6, 7, 8, 9, 10

Dus de telling hiervan zou max – min + 1 zijn.

d.w.z. 10 – 5 + 1 = 6

Het willekeurige getal genereert een getal tussen 0-5.

d.w.z. 0, 1, 2, 3, 4, 5

Het toevoegen van de min waarde aan het willekeurige getal zou het volgende opleveren:

5, 6, 7, 8, 9, 10

Hierdoor verkrijgen we het gewenste bereik.


Antwoord 15

 rand.nextInt((max+1) - min) + min;

Antwoord 16

Vanaf Java 7 mag u Random niet langer gebruiken. Voor de meeste toepassingen is de
willekeurige nummergenerator naar keuze is nu
ThreadLocalRandom.

Voor fork join pools en parallel
streams, gebruik SplittableRandom.

Jozua Bloch. Effectieve Java. Derde editie.

Vanaf Java 8

Gebruik voor fork-join-pools en parallelle streams SplittableRandom dat meestal sneller is, betere statistische onafhankelijkheid en uniformiteitseigenschappen heeft in vergelijking met Random.

Een willekeurige int genereren in het bereik [0, 1_000]:

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

Een willekeurige reeks int[100] met waarden in het bereik [0, 1_000]:

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

Een stroom van willekeurige waarden retourneren:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);

Antwoord 17

Genereer een willekeurig getal voor het verschil van min en max met behulp van de nextint(n) methode en voeg dan min nummer toe aan het resultaat:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);

Antwoord 18

Gebruik gewoon de klasse Random:

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);

Antwoord 19

Gebruik de volgende code om een ​​willekeurig getal “tussen twee getallen” te genereren:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

Dit geeft u een willekeurig getal tussen 1 (inclusief) en 11 (exclusief), dus initialiseer de waarde voor de bovengrens door 1 toe te voegen. Als u bijvoorbeeld een willekeurig getal tussen 1 en 10 wilt genereren, initialiseert u het bovengrensnummer met 11 in plaats van 10.


Antwoord 20

Deze methode kan handig zijn om te gebruiken:

Deze methode retourneert een willekeurig getal tussen de opgegeven minimum- en maximumwaarde:

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;
    }
}

en deze methode retourneert een willekeurig getal van de opgegeven min en max waarde (dus het gegenereerde getal kan ook het min of max getal zijn):

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

Antwoord 21

In het geval van het gooien van een dobbelsteen zou het een willekeurig getal zijn tussen 1 en 6 (niet 0 tot 6), dus:

face = 1 + randomNumbers.nextInt(6);

Antwoord 22

int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

Of bekijk RandomUtils van Apache Commons.


Antwoord 23

Hier is een handige klasse om willekeurige ints te genereren in een bereik met elke combinatie van inclusieve/exclusieve grenzen:

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;
    }
}

Antwoord 24

Dat kun je op een beknopte manier bereiken in 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);

Antwoord 25

Een andere optie is gewoon het gebruik van 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);
    // ...
 }

Antwoord 26

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);
}

Antwoord 27

Ik vond dit voorbeeld Willekeurige getallen genereren :


Dit voorbeeld genereert willekeurige gehele getallen in een specifiek bereik.

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);
  }
} 

Een voorbeeld van deze klasse:

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.

Antwoord 28

rand.nextInt((max+1) - min) + min;

Dit werkt prima.


Antwoord 29

Het is beter om SecureRandom te gebruiken dan alleen willekeurig.

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;
}

Antwoord 30

Hier is een eenvoudig voorbeeld dat laat zien hoe u een willekeurig getal genereert uit een gesloten [min, max]-bereik, terwijl min <= max is true

Je kunt het hergebruiken als veld in hole class, waarbij je ook alle Random.class methoden op één plek hebt staan

Resultatenvoorbeeld:

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

Bronnen:

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;
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here

nine + eighteen =

Other episodes