4099 Stimmen

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

Wie generiere ich eine zufällige int Wert in einem bestimmten Bereich?

Ich habe Folgendes versucht, aber das funktioniert nicht:

Versuch 1:

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

Fehler: randomNum kann größer sein als maximum .

Versuch 2:

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

Fehler: randomNum kann kleiner sein als minimum .

0 Stimmen

Wenn Sie viele Zufallszahlen benötigen, empfehle ich die Klasse Random in der API nicht. Sie hat einfach eine zu kleine Periode. Versuchen Sie die Mersenne-Twister stattdessen. Es gibt eine Java-Implementierung .

46 Stimmen

Bevor Sie eine neue Antwort schreiben, bedenken Sie, dass es bereits mehr als 65 Antworten auf diese Frage gibt. Bitte stellen Sie sicher, dass Ihre Antwort Informationen enthält, die nicht in den vorhandenen Antworten enthalten sind.

53voto

Joel Sjöstrand Punkte 625

Verzeihen Sie mir, dass ich anspruchsvoll bin, aber die von der Mehrheit vorgeschlagene Lösung, d.h., min + rng.nextInt(max - min + 1)) scheint gefährlich zu sein, denn:

  • rng.nextInt(n) kann nicht erreichen Integer.MAX_VALUE .
  • (max - min) kann zu einem Überlauf führen, wenn min negativ ist.

Eine narrensichere Lösung würde korrekte Ergebnisse für jede min <= max innerhalb von [ Integer.MIN_VALUE , Integer.MAX_VALUE ]. Betrachten Sie die folgende naive Implementierung:

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

Obwohl ineffizient, ist zu beachten, dass die Erfolgswahrscheinlichkeit im while Schleife wird immer 50% oder höher sein.

0 Stimmen

Warum nicht eine IllegalArgumentException auslösen, wenn die Differenz = Integer.MAX_VALUE ist? Dann brauchen Sie die while-Schleife nicht.

3 Stimmen

@mpkorstanje Diese Implementierung ist so konzipiert, dass sie mit allen Werten von min <= max funktioniert, auch wenn ihre Differenz gleich oder sogar größer als MAX_VALUE ist. In diesem Fall ist es üblich, eine Schleife bis zum Erfolg laufen zu lassen, um eine gleichmäßige Verteilung zu gewährleisten (wenn die zugrunde liegende Zufallsquelle gleichmäßig ist). Random.nextInt(int) macht das intern, wenn das Argument keine Potenz von 2 ist.

35voto

Chinnery Punkte 10029

Ich frage mich, ob eine der Methoden zur Erzeugung von Zufallszahlen, die von einem Apache Commons Mathematik Die Bibliothek würde sich dafür eignen.

Zum Beispiel: RandomDataGenerator.nextInt o RandomDataGenerator.nextLong

34voto

Simon Punkte 2276

Ich benutze dies:

 /**
   * @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;
 }

Sie können es in einen Integer umwandeln, wenn Sie wollen.

0 Stimmen

Diese Funktion ergibt immer wieder die gleiche Zahl. In meinem Fall war es: 2147483647

0 Stimmen

Fail: Sie haben eine Funktion, die einen Double benötigt und dann + 1 ausführt? Das verstößt sicherlich gegen das Prinzip der geringsten Überraschung. Was passiert, wenn Sie min = 0,1 und max = 0,2 verwenden?

0 Stimmen

@sokras die Methode ruft auf new Random (siehe JavaDoc): "Erzeugt einen neuen Zufallszahlengenerator. Dieser Konstruktor setzt den Seed des Zufallszahlengenerators auf einen Wert, der sich sehr wahrscheinlich von jedem anderen Aufruf dieses Konstruktors unterscheidet." Sehr wahrscheinlich könnte auch bedeuten, dass die aktuelle Zeit als Seed verwendet wird. Wenn diese Zeit in Millisekunden angegeben ist, dann sind die heutigen Computer schnell genug, um die gleiche Zahl zu erzeugen. Aber abgesehen davon ist 2147483647 Integer.MAX_VALUE Die Ausgabe hängt natürlich von der Eingabe ab, die Sie nicht angegeben haben.

34voto

Oleksandr Pyrohov Punkte 13894

Ab Java 7 sollten Sie nicht mehr mit Random . Für die meisten Anwendungen ist die Zufallszahlengenerator der Wahl ist jetzt ThreadLocalRandom .

Für Fork-Join-Pools und parallele Streams, verwenden Sie SplittableRandom .

Joshua Bloch. Effektives Java. Dritte Auflage.

Ausgehend von Java 8

Für Fork-Join-Pools und parallele Streams verwenden Sie SplittableRandom das in der Regel schneller ist, eine bessere statistische Unabhängigkeit und Gleichmäßigkeitseigenschaften im Vergleich zu Random .

Um einen Zufallswert zu erzeugen int im Bereich [0, 1_000]:

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

Um einen Zufallswert zu erzeugen int[100] Array mit Werten aus dem Bereich [0, 1_000]:

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

Um einen Stream von Zufallswerten zurückzugeben:

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

0 Stimmen

Gibt es einen Grund, warum das Beispiel eine .parallel() ? Mir scheint, dass die Generierung von 100 Zufallszahlen zu trivial wäre, um Parallelität zu rechtfertigen.

0 Stimmen

@Johnbot Danke für den Kommentar, Sie haben recht. Aber der Hauptgrund war, eine API zu zeigen (natürlich ist der klügere Weg, die Leistung zu messen, bevor man parallel Verarbeitung). Übrigens, für Array von 1_000_000 Elemente, die parallel Version war auf meinem Rechner im Vergleich zur sequenziellen Version 2 mal schneller.

31voto

Sunil Chawla Punkte 341

Nehmen wir ein Beispiel.

Angenommen, ich möchte eine Zahl zwischen 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);

Das müssen wir verstehen ...

Initialisieren Sie max mit dem höchsten Wert und min mit dem niedrigsten Wert.

Nun müssen wir bestimmen, wie viele mögliche Werte erhalten werden können. Für dieses Beispiel wäre dies der Fall:

5, 6, 7, 8, 9, 10

Die Anzahl wäre also max - min + 1.

d.h. 10 - 5 + 1 = 6

Die Zufallszahl generiert eine Zahl zwischen 0-5 .

d.h. 0, 1, 2, 3, 4, 5

Hinzufügen der min Wert auf die Zufallszahl übertragen würde:

5, 6, 7, 8, 9, 10

So erhalten wir die gewünschte Reichweite.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X