Frage Wie erzeuge ich zufällige Ganzzahlen innerhalb eines bestimmten Bereichs in Java?


Wie erzeuge ich eine Zufallszahl? int Wert in einem bestimmten Bereich?

Ich habe folgendes versucht, aber das funktioniert nicht:

Versuch 1:

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

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

2897
2017-12-12 18:20


Ursprung


Antworten:


Im Java 1.7 oder späterDer Standardweg ist wie folgt:

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

Sehen das relevante JavaDoc. Dieser Ansatz hat den Vorteil, dass Sie a nicht explizit initialisieren müssen java.util.Random Beispiel, das bei unsachgemäßer Verwendung zu Verwirrung und Fehlern führen kann.

Umgekehrt gibt es jedoch keine Möglichkeit, den Seed explizit festzulegen, so dass es schwierig sein kann, Ergebnisse in Situationen zu reproduzieren, in denen dies nützlich ist, beispielsweise beim Testen oder Speichern von Spielständen oder Ähnlichem. In diesen Situationen kann die vorstehende Java 1.7-Technik verwendet werden.

Vor Java 1.7Der Standardweg ist wie folgt:

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

Sehen das relevante JavaDoc. In der Praxis, die java.util.Random Klasse ist oft vorzuziehen java.lang.Math.random ().

Insbesondere ist es nicht notwendig, das zufallsgenerierende Zufallsgeneratorrad neu zu erfinden, wenn es eine einfache API innerhalb der Standardbibliothek gibt, um die Aufgabe zu erfüllen.


3254
2017-12-12 18:25



Beachten Sie, dass dieser Ansatz eher voreingenommen und weniger effizient ist als a nextInt Ansatz, https://stackoverflow.com/a/738651/360211

Ein Standardmuster dafür ist:

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

Das Java Mathematische Bibliotheksfunktion Math.random () erzeugt einen doppelten Wert im Bereich [0,1). Beachten Sie, dass dieser Bereich nicht die 1 enthält.

Um zuerst einen bestimmten Wertebereich zu erhalten, müssen Sie mit der Größe des Wertebereichs multiplizieren, den Sie abdecken möchten.

Math.random() * ( Max - Min )

Dies gibt einen Wert in dem Bereich zurück [0,Max-Min), wo 'Max-Min' nicht enthalten ist.

Zum Beispiel, wenn du willst [5,10), müssen Sie fünf ganzzahlige Werte abdecken, die Sie verwenden

Math.random() * 5

Dies würde einen Wert in dem Bereich zurückgeben [0,5), wo 5 nicht enthalten ist.

Jetzt müssen Sie diesen Bereich auf den Bereich verschieben, auf den Sie ausgerichtet sind. Sie tun dies, indem Sie den Min-Wert hinzufügen.

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

Sie erhalten nun einen Wert im Bereich [Min,Max). Dies entspricht unserem Beispiel [5,10):

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

Aber das schließt immer noch nicht ein Max und du bekommst einen doppelten Wert. Um das zu bekommen Max Wert enthalten, müssen Sie 1 zu Ihrem Bereichsparameter hinzufügen (Max - Min) und dann den Dezimalteil abschneiden, indem Sie ihn in einen int umwandeln. Dies geschieht über:

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

Und da hast du es. Ein zufälliger ganzzahliger Wert im Bereich [Min,Max]oder nach dem Beispiel [5,10]:

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

1323
2017-12-12 18:35



Benutzen:

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

Die Ganzzahl x ist jetzt die Zufallszahl, die ein mögliches Ergebnis von hat 5-10.


311
2017-09-04 04:23



Benutzen:

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

122
2017-12-12 18:25



Mit  Sie führten die Methode ein ints(int randomNumberOrigin, int randomNumberBound) in dem Random Klasse.

Wenn Sie zum Beispiel fünf zufällige Ganzzahlen (oder eine einzige) im Bereich [0, 10] erzeugen wollen, tun Sie Folgendes:

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

Der erste Parameter zeigt nur die Größe des IntStream erzeugt (das ist die überladene Methode desjenigen, der ein unbegrenztes erzeugt IntStream).

Wenn Sie mehrere separate Aufrufe ausführen müssen, können Sie einen unendlichen primitiven Iterator aus dem Stream erstellen:

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

Sie können es auch tun für double und long Werte.

Ich hoffe es hilft! :)


98
2017-11-26 18:29



Sie können Ihr zweites Codebeispiel wie folgt bearbeiten:

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

90
2017-12-12 18:31



Nur eine kleine Modifikation Ihrer ersten Lösung würde ausreichen.

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

Siehe hier zur Implementierung von Random


89
2018-03-12 22:44