Wie generiere ich einen zufälligen int
Wert in einem bestimmten Bereich?
Ich habe folgendes versucht, aber diese funktionieren 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`.
Antworten:
In Java 1.7 oder höher lautet die Standardmethode hierfür:
Siehe das entsprechende JavaDoc . Dieser Ansatz hat den Vorteil, dass eine java.util.Random- Instanz nicht explizit initialisiert werden muss. Dies kann bei unsachgemäßer Verwendung zu Verwirrung und Fehlern führen.
Umgekehrt gibt es jedoch keine Möglichkeit, den Startwert explizit festzulegen, sodass es schwierig sein kann, Ergebnisse in Situationen zu reproduzieren, in denen dies nützlich ist, z. B. beim Testen oder Speichern von Spielzuständen oder ähnlichem. In diesen Situationen kann die unten gezeigte Technik vor Java 1.7 verwendet werden.
Vor Java 1.7 ist dies standardmäßig wie folgt:
Siehe das entsprechende JavaDoc . In der Praxis ist die Klasse java.util.Random häufig java.lang.Math.random () vorzuziehen .
Insbesondere muss das Zufallsgenerierungsrad nicht neu erfunden werden, wenn die Standardbibliothek eine einfache API enthält, um die Aufgabe auszuführen.
quelle
max
Wert angegeben istInteger.MAX_VALUE
, kann ein Überlauf auftreten, der zu a führtjava.lang.IllegalArgumentException
. Sie können versuchen mit :randInt(0, Integer.MAX_VALUE)
. WennnextInt((max-min) + 1)
der höchste Wert zurückgegeben wird (ich nehme an, ziemlich selten), läuft er dann nicht wieder über (vorausgesetzt, min und max sind hoch genug)? Wie gehe ich mit solchen Situationen um?ThreadLocalRandom
wurde 2 1/2 Jahre nach der ersten Beantwortung dieser Frage zu Java hinzugefügt. Ich war immer der festen Meinung, dass die Verwaltung der Zufallsinstanz außerhalb des Rahmens der Frage liegt.Beachten Sie, dass dieser Ansatz voreingenommener und weniger effizient ist als der
nextInt
Ansatz https://stackoverflow.com/a/738651/360211Ein Standardmuster, um dies zu erreichen, ist:
Die Java Math-Bibliotheksfunktion Math.random () generiert einen doppelten Wert im Bereich
[0,1)
. Beachten Sie, dass dieser Bereich die 1 nicht enthält.Um zuerst einen bestimmten Wertebereich zu erhalten, müssen Sie mit der Größe des Wertebereichs multiplizieren, den Sie abdecken möchten.
Dies gibt einen Wert im Bereich zurück
[0,Max-Min)
, in dem 'Max-Min' nicht enthalten ist.Wenn Sie beispielsweise möchten
[5,10)
, müssen Sie fünf ganzzahlige Werte abdecken, damit Sie sie verwenden könnenDies würde einen Wert im Bereich zurückgeben
[0,5)
, in dem 5 nicht enthalten ist.Jetzt müssen Sie diesen Bereich auf den Bereich verschieben, auf den Sie abzielen. Sie tun dies, indem Sie den Min-Wert hinzufügen.
Sie erhalten nun einen Wert im Bereich
[Min,Max)
. Nach unserem Beispiel bedeutet das[5,10)
:Dies ist jedoch immer noch nicht enthalten
Max
und Sie erhalten einen doppelten Wert. Um denMax
Wert aufzunehmen, müssen Sie Ihrem Bereichsparameter 1 hinzufügen(Max - Min)
und dann den Dezimalteil abschneiden, indem Sie ihn in ein int umwandeln. Dies erfolgt über:Und da hast du es. Ein zufälliger ganzzahliger Wert im Bereich
[Min,Max]
oder gemäß dem Beispiel[5,10]
:quelle
Verwenden:
Die Ganzzahl
x
ist jetzt die Zufallszahl, deren Ergebnis möglicherweise ist5-10
.quelle
Verwenden:
quelle
Mit Java-8Sie führten die Methode
ints(int randomNumberOrigin, int randomNumberBound)
in derRandom
Klasse ein.Wenn Sie beispielsweise fünf zufällige Ganzzahlen (oder eine einzelne) im Bereich [0, 10] generieren möchten, gehen Sie einfach wie folgt vor:
Der erste Parameter gibt nur die Größe des
IntStream
generierten Parameters an (dies ist die überladene Methode derjenigen, die eine unbegrenzte erzeugtIntStream
).Wenn Sie mehrere separate Aufrufe ausführen müssen, können Sie aus dem Stream einen unendlichen primitiven Iterator erstellen:
Sie können dies auch für
double
undlong
Werte tun . Ich hoffe, es hilft! :) :)quelle
streamSize
der erste Parameter dieser Methode hatstreamSize !=0
. Was ist der Unterschied, wennstreamSize
1/2 / n gegeben ist?Sie können Ihr zweites Codebeispiel wie folgt bearbeiten:
quelle
Nur eine kleine Modifikation Ihrer ersten Lösung würde ausreichen.
Weitere Informationen zur Implementierung von finden Sie hier
Random
quelle
ThreadLocalRandom
Äquivalent der Klassejava.util.Random
für eine Multithread-Umgebung. Das Generieren einer Zufallszahl erfolgt lokal in jedem der Threads. Wir haben also eine bessere Leistung, indem wir die Konflikte reduzieren.x
,y
- Intervalle zB (1,10)quelle
Die
Math.Random
Klasse in Java basiert auf 0. Also, wenn Sie so etwas schreiben:x
wird zwischen sein0-9
inklusive sein.Bei dem folgenden Array von
25
Elementen lautet der Code zum Generieren einer Zufallszahl zwischen0
(der Basis des Arrays) undarray.length
:Da
i.length
wird zurückgegeben25
,nextInt( i.length )
wird der eine Zahl zwischen dem Bereich von zurückgeben0-24
. Die andere OptionMath.Random
funktioniert genauso.Weitere Informationen finden Sie im Forum-Beitrag Zufällige Intervalle (archive.org) .
quelle
index
Variable hat keinen Einfluss auf das Ergebnis der Zufallszahl. Sie können es nach Belieben initialisieren, ohne sich Gedanken über die Änderung des Ergebnisses machen zu müssen. Hoffe das hilft.int index = rand.nextInt(i.Length);
int index; \n index = rand...
wenn man Erklärungen und Aufgaben in verschiedenen Zeilen mag. Einige Codierungsstandards sind strenger (und ohne offensichtlichen Zweck) als andere.Verzeihen Sie mir, dass ich anspruchsvoll bin, aber die von der Mehrheit vorgeschlagene Lösung, dh
min + rng.nextInt(max - min + 1))
, scheint gefährlich zu sein, weil:rng.nextInt(n)
kann nicht erreichenInteger.MAX_VALUE
.(max - min)
kann einen Überlauf verursachen, wenn ermin
negativ ist.Eine narrensichere Lösung würde korrekte Ergebnisse für alle
min <= max
innerhalb von [Integer.MIN_VALUE
,Integer.MAX_VALUE
] zurückgeben. Betrachten Sie die folgende naive Implementierung:Beachten Sie, dass die Erfolgswahrscheinlichkeit in der
while
Schleife immer 50% oder mehr beträgt, obwohl sie ineffizient ist .quelle
Dies kann durch einfaches Ausführen der folgenden Anweisung erfolgen:
Unten ist der Quellcode
Randomizer.java
Es ist einfach sauber und einfach.
quelle
Ich frage mich, ob eine der Zufallszahlengenerierungsmethoden, die von einer Apache Commons Math- Bibliothek bereitgestellt werden, in die Rechnung passt.
Zum Beispiel:
RandomDataGenerator.nextInt
oderRandomDataGenerator.nextLong
quelle
Nehmen wir ein Beispiel.
Angenommen, ich möchte eine Zahl zwischen 5 und 10 generieren :
Lassen Sie uns das verstehen ...
quelle
quelle
Generieren Sie eine Zufallszahl für die Differenz von min und max mithilfe der nextint (n) -Methode und fügen Sie dann dem Ergebnis eine min-Zahl hinzu:
quelle
Ich benutze das:
Sie können es in eine Ganzzahl umwandeln, wenn Sie möchten.
quelle
new Random
(überprüfen Sie das JavaDoc): "Erstellt einen neuen Zufallszahlengenerator. Dieser Konstruktor setzt den Startwert des Zufallszahlengenerators auf einen Wert, der sich sehr wahrscheinlich von jedem anderen Aufruf dieses Konstruktors unterscheidet." Sehr wahrscheinlich wird nur die aktuelle Zeit als Startwert verwendet. Wenn diese Zeit Millisekunden benötigt, sind die aktuellen Computer schnell genug, um dieselbe Zahl zu generieren. Aber außerdem ist 2147483647Integer.MAX_VALUE
; Die Ausgabe hängt offensichtlich von der Eingabe ab, die Sie nicht angegeben haben.Joshua Bloch. Effektives Java. Dritte Edition.
Ab Java 8
Bei Fork-Join-Pools und parallelen Streams ist die Verwendung
SplittableRandom
, die normalerweise schneller ist, im Vergleich zu statistisch besser und einheitlicherRandom
.Um einen Zufall
int
im Bereich zu generieren[0, 1_000]:
So generieren Sie ein zufälliges
int[100]
Array von Werten im Bereich[0, 1_000]:
So geben Sie einen Stream mit zufälligen Werten zurück:
quelle
.parallel()
? Es scheint mir, als wäre das Generieren von 100 Zufallszahlen zu trivial, um Parallelität zu rechtfertigen.parallel
Verarbeitung zu messen ). Übrigens1_000_000
war dieparallel
Version für eine Reihe von Elementen auf meinem Computer im Vergleich zur sequentiellen Version zweimal schneller.Verwenden Sie einfach die Zufallsklasse :
quelle
Diese Methoden sind möglicherweise bequem zu verwenden:
Diese Methode gibt eine Zufallszahl zwischen dem angegebenen Min- und Max-Wert zurück:
und diese Methode gibt eine Zufallszahl aus dem angegebenen Min- und Max-Wert zurück (die generierte Zahl kann also auch die Min- oder Max-Zahl sein):
quelle
// Since the random number is between the min and max values, simply add 1
. Warum? Zählt min nicht? Normalerweise ist der Bereich [min, max], wobei min eingeschlossen und max ausgeschlossen ist. Falsche Antwort, abgelehnt.min + 1
ist doppelt so wahrscheinlich wie die andere Zahl das Ergebnis vongetRandomNumberBetween
!Im Falle eines Würfelns wäre es eine Zufallszahl zwischen 1 und 6 (nicht 0 bis 6), also:
quelle
Oder werfen Sie einen Blick auf RandomUtils von Apache Commons .
quelle
Double.valueOf(Math.random()*(maximum-minimun)).intValue()
ist eine ziemlich verschleierte (und ineffiziente) Art zu sagen(int)(Math.random()*(maximum-minimun))
...Hier ist eine hilfreiche Klasse, um Zufallszahlen
ints
in einem Bereich mit einer beliebigen Kombination von Inklusiv- / Exklusivgrenzen zu generieren :quelle
Verwenden Sie den folgenden Code, um eine Zufallszahl "zwischen zwei Zahlen" zu generieren:
Dies gibt Ihnen eine Zufallszahl zwischen 1 (einschließlich) und 11 (exklusiv). Initialisieren Sie also den UpperBound-Wert durch Hinzufügen von 1. Wenn Sie beispielsweise eine Zufallszahl zwischen 1 und 10 generieren möchten, initialisieren Sie die UpperBound-Zahl mit 11 anstelle von 11 10.
quelle
Sie können dies in Java 8 präzise erreichen:
quelle
quelle
Eine andere Option ist nur die Verwendung von Apache Commons :
quelle
Ich habe dieses Beispiel gefunden. Zufallszahlen generieren :
In diesem Beispiel werden zufällige Ganzzahlen in einem bestimmten Bereich generiert.
Ein Beispiellauf dieser Klasse:
quelle
Es ist besser, SecureRandom als nur Random zu verwenden.
quelle
private static int SecureRandom rand = new SecureRandom();
static {
rand.setSeed(...);
}
SecureRandom
, es wird vom System ausgesät. Direktes AnrufensetSeed
ist sehr gefährlich, es kann den (wirklich zufälligen) Startwert durch das Datum ersetzen. Und das wird sicherlich nicht zu einem Ergebnis führenSecureRandom
, da jeder die Zeit erraten und versuchen kann, seine eigeneSecureRandom
Instanz mit diesen Informationen zu versehen.Hier ist ein einfaches Beispiel, das zeigt, wie Zufallszahlen aus dem geschlossenen
[min, max]
Bereich generiert werdenmin <= max is true
Sie können es als Feld in der Lochklasse wiederverwenden und alle
Random.class
Methoden an einem Ort habenErgebnisbeispiel:
Quellen:
quelle
Das funktioniert gut.
quelle