random do - Come generare numeri casuali all'interno di un intervallo specifico in Java?




use value (25)

Puoi modificare il tuo secondo esempio di codice per:

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

Come posso generare un valore int casuale in un intervallo specifico?

Ho provato quanto segue, ma quelli non funzionano:

Tentativo 1:

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

Tentativo 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`.

ThreadLocalRandom equivalente della classe java.util.Random per l'ambiente multithread. La generazione di un numero casuale viene eseguita localmente in ciascuna delle discussioni. Quindi abbiamo una performance migliore riducendo i conflitti.

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

x, y - intervalli es. (1,10)


In caso di lancio di un dado, sarebbe un numero casuale compreso tra 1 e 6 (non da 0 a 6), quindi:

face = 1 + randomNumbers.nextInt(6);

Un'altra opzione è solo usando 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);
    // ...
 }

Uso:

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

Il numero intero x è ora il numero casuale con un possibile risultato di 5-10 .


Usa la classe Random :

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

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

Oppure dai un'occhiata a RandomUtils da Apache Commons .


La classe Math.Random in Java è a base 0. Quindi, se scrivi qualcosa come questo:

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

x sarà compreso tra 0-9 inclusi.

Quindi, data la seguente matrice di 25 elementi, il codice per generare un numero casuale compreso tra 0 (la base dell'array) e array.length sarebbe:

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

index = rand.nextInt( i.length );

Poiché i.length restituirà 25 , nextInt( i.length ) restituirà un numero compreso tra 0-24 . L'altra opzione è con Math.Random che funziona allo stesso modo.

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

Per una migliore comprensione, controlla il forum post Random Intervals (archive.org) .


Ecco una classe utile per generare ints casuali in un intervallo con qualsiasi combinazione di limiti inclusivi / esclusivi:

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

Questo metodo potrebbe essere comodo da usare:

Questo metodo restituirà un numero casuale tra il valore min e max fornito:

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

e questo metodo restituirà un numero casuale dal valore min e max fornito (quindi il numero generato potrebbe anche essere il numero minimo o massimo):

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

    return randomNumber;
}

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

Solo una piccola modifica della tua prima soluzione sarebbe sufficiente.

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

Vedi di più qui per l'implementazione di Random


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

Funziona bene


Ecco un semplice esempio che mostra come generare un numero casuale da un intervallo chiuso [min, max] , mentre min <= max is true

Puoi riutilizzarlo come campo in classe buca, avendo anche tutti i metodi Random.class in un posto

Esempio di risultati:

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

fonti:

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

Facciamo un esempio.

Supponiamo di voler generare un numero compreso tra 5 e 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);

Cerchiamo di capirlo ...

Inizializza max con il valore più alto e min con il valore più basso.

Ora, dobbiamo determinare quanti valori possibili possono essere ottenuti. Per questo esempio, sarebbe:

5, 6, 7, 8, 9, 10

Quindi, il conteggio di questo sarebbe max - min + 1.

cioè 10 - 5 + 1 = 6

Il numero casuale genererà un numero compreso tra 0 e 5 .

cioè 0, 1, 2, 3, 4, 5

L'aggiunta del valore minimo al numero casuale produrrebbe:

5, 6, 7, 8, 9, 10

Quindi otteniamo la gamma desiderata.


Perdonami per essere meticoloso, ma la soluzione suggerita dalla maggioranza, cioè min + rng.nextInt(max - min + 1)) , sembra pericolosa a causa del fatto che:

  • rng.nextInt(n) non può raggiungere Integer.MAX_VALUE .
  • (max - min) può causare overflow quando min è negativo.

Una soluzione infallibile restituirebbe risultati corretti per qualsiasi min <= max entro [ Integer.MIN_VALUE , Integer.MAX_VALUE ]. Considera la seguente implementazione ingenua:

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

Sebbene inefficiente, si noti che la probabilità di successo nel ciclo while sarà sempre del 50% o superiore.


A partire da Java 7, non dovresti più usare Random . Per la maggior parte degli usi, il generatore di numeri casuali di scelta è ora ThreadLocalRandom .

Per i pool di fork join e i flussi paralleli, utilizzare SplittableRandom .

Joshua Bloch. Efficace Java. Terza edizione.

A partire da Java 8

Per i pool di fork join e i flussi paralleli, utilizzare SplittableRandom che è in genere più veloce, ha una migliore indipendenza statistica e proprietà di uniformità rispetto a Random .

Per generare un intervallo casuale nell'intervallo [0, 1_000]:

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

Per generare una matrice di valori int[100] casuali nell'intervallo [0, 1_000]:

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

Per restituire un flusso di valori casuali:

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

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

Con java-8 hanno introdotto gli ints(int randomNumberOrigin, int randomNumberBound) del metodo ints(int randomNumberOrigin, int randomNumberBound) nella classe Random .

Ad esempio, se vuoi generare cinque numeri interi casuali (o uno solo) nell'intervallo [0, 10], esegui semplicemente:

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

Il primo parametro indica solo la dimensione IntStream generato (che è il metodo sovraccarico di quello che produce un IntStream illimitato).

Se devi effettuare più chiamate separate, puoi creare un iteratore primitivo infinito dallo stream:

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

Puoi anche farlo per valori double e long .

Spero che sia d'aiuto! :)



Si noti che questo approccio è più parziale e meno efficiente di un approccio nextInt , https://.com/a/738651/360211

Uno schema standard per realizzare questo è:

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

La funzione di libreria Math Math Math.random () genera un doppio valore nell'intervallo [0,1) . Si noti che questo intervallo non include il 1.

Per ottenere innanzitutto un intervallo di valori specifico, è necessario moltiplicare per la grandezza dell'intervallo di valori che si desidera coprire.

Math.random() * ( Max - Min )

Ciò restituisce un valore nell'intervallo [0,Max-Min) , dove 'Max-Min' non è incluso.

Ad esempio, se si desidera [5,10) , è necessario coprire cinque valori interi in modo da utilizzare

Math.random() * 5

Ciò restituirebbe un valore nell'intervallo [0,5) , in cui 5 non è incluso.

Ora devi spostare questo intervallo fino all'intervallo che hai scelto come target. Lo fai aggiungendo il valore Min.

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

Ora otterrai un valore nell'intervallo [Min,Max) . Seguendo il nostro esempio, ciò significa [5,10) :

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

Ma questo non include ancora Max e ottieni un doppio valore. Per ottenere il valore Max incluso, devi aggiungere 1 al tuo parametro di intervallo (Max - Min) e quindi troncare la parte decimale eseguendo il casting su un int. Questo è realizzato tramite:

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

E il gioco è fatto. Un valore intero casuale nell'intervallo [Min,Max] o per l'esempio [5,10] :

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

In Java 1.7 o versioni successive , il modo standard per farlo è il seguente:

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

Vedi il relativo JavaDoc . Questo approccio ha il vantaggio di non dover inizializzare esplicitamente un'istanza java.util.Random , che può essere fonte di confusione ed errore se usata in modo inappropriato.

Tuttavia, viceversa, non è possibile impostare in modo esplicito il seed in modo che possa essere difficile riprodurre i risultati in situazioni in cui ciò è utile, come test o salvataggio di stati di gioco o simili. In queste situazioni, è possibile utilizzare la tecnica pre-Java 1.7 mostrata di seguito.

Prima di Java 1.7 , il modo standard per farlo è il seguente:

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

Vedi il relativo JavaDoc . In pratica, la classe java.util.Random è spesso preferibile a java.lang.Math.random() .

In particolare, non è necessario reinventare la ruota di generazione di numeri casuali quando vi è un'API semplice all'interno della libreria standard per eseguire l'operazione.


Ho trovato questo esempio Genera numeri casuali :

Questo esempio genera numeri casuali in un intervallo specifico.

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 esempio di esecuzione di questa 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.

È meglio usare SecureRandom piuttosto che solo Random.

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

So che questa domanda ha già una risposta, ma la mia risposta potrebbe aiutare qualcuno.

Ho trovato questo semplice metodo su W3Schools:

Math.floor((Math.random() * max) + min);

Spero che questo possa aiutare qualcuno.





java random integer