5.4 Die Random-Klasse
Neben der Zufallsfunktion Math.random() in der Klasse Math, gibt es einen flexibleren Generator für Zufallszahlen im Util-Paket. Dies ist die Klasse Random, die aber im Gegensatz zu Math.random() keine statischen Methoden besitzt. Die statische Funktion aus der Klasse Math nutzt intern jedoch auch ein Random-Objekt.
Startwert für jede Zufallszahl ist ein 48-Bit-Seed. »Seed« ist das englische Wort für Samen und deutet an, dass es bei der Generierung von Zufallszahlen wie bei Pflanzen einen Samen gibt, der zu Nachkommen führt. Aus diesem Startwert ermitteln sich anschließend die anderen Zahlen durch lineare Kongruenzen.1 (Dadurch sind die Zahlen nicht wirklich zufällig, sondern sie gehorchen einem mathematischen Verfahren. Kryptografisch bessere Zufallszahlen liefert dagegen die Klasse SecureRandom.) Zunächst ist daher, bevor Zufallszahlen erzeugt werden, ein Exemplar der Klasse Random zu erstellen. Dieses Exemplar wird mit einem Zufallswert (Datentyp long) initialisiert, der dann für die weiteren Berechnungen verwendet wird. Dieser Startwert prägt die ganze Folge von erzeugten Zufallszahlen, obwohl nicht ersichtlich ist, wie die Folge sich verhält. Doch eines ist gewiss: Zwei mit gleichen Startwerten erzeugte Random-Objekte liefern auch dieselbe Folge von Zufallszahlen. Da einem meist nicht der passende Startwert für einen Zufallszahlen-Generator einfällt, ist der parameterlose Standard-Konstruktor wie folgt implementiert:
Random() {
this( System.currentTimeMillis() );
}
Der Konstruktor benutzt folglich die aktuelle Zeit als Startwert für die folgenden Zufallszahlen.
class java.util.Random
implements Serializable
|
|
Random()
Erzeugt einen neuen Zufallszahlen-Generator. Seed wird auf die aktuelle Zeit gesetzt. |
|
Random( long seed )
Erzeugt einen neuen Zufallszahlen-Generator und benutzt den Parameter seed als Startwert. |
|
void setSeed( long seed )
Setzt den Seed neu. Der Generator verhält sich anschließend genauso wie ein mit diesem Seed-Wert frisch erzeugter Generator. |
Die Random-Klasse erzeugt Zufallszahlen für vier verschiedene Datentypen: int (32 Bit), long (64 Bit), double und float. Dafür stehen vier Funktionen zur Verfügung:
|
int nextInt()
long nextLong()
Liefert die nächste Pseudo-Zufallszahl zwischen Integer.MIN_VALUE und Integer.MAX_VALUE beziehungsweise Long.MIN_VALUE und Long.MAX_VALUE. |
|
float nextFloat()
double nextDouble()
Liefert die nächste Pseudo-Zufallszahl zwischen 0.0 und 1.0. |
|
int nextInt( int range )
Liefert eine int-Pseudo-Zufallszahl im Bereich von 0 bis range. |
Die Klasse Random verfügt über eine besondere Methode, mit der sich eine Reihe von Zufallszahlen erzeugen lassen. Dies ist die Funktion nextBytes(byte[]). Der Parameter ist ein Bytefeld, und dieses wird komplett mit Zufallszahlen gefüllt:
|
void nextBytes( byte bytes[] )
Füllt das Feld mit Zufalls-Bytes auf. |
Zur Erzeugung aller Zufallszahlen wird die Funktion next() verwendet, die in Random implementiert ist, aber nicht sofort genutzt werden kann. Sie ist protected und kann somit nur von einer erbenden Klasse aufgerufen oder überschrieben werden.
Pseudo-Zufallszahlen in der Normalverteilung
Über eine spezielle Funktion können wir Zufallszahlen erhalten, die einer Normalverteilung genügen: nextGaussian(). Diese Funktion arbeitet nach der Polar-Methode2 und erzeugt aus zwei unabhängigen Pseudo-Zufallszahlen zwei normal verteilte Zahlen. Der Mittelpunkt liegt bei 0, und die Standardabweichung ist 1. Die Zahlen, die von der Funktion nextGaussian() berechnet werden, sind double-Zahlen und häufig in der Nähe von 0. Größere Zahlen sind der Wahrscheinlichkeit nach seltener.
class java.util.Random
implements Serializable
|
|
double nextGaussian()
Liefert die nächste Zufallszahl in einer Gaußschen Normalverteilung mit der Mitte 0.0 und der Standardabweichung 1.0. |
1 Donald E. Knuth (DEK), The Art of Computer Programming (ACP), 2. Buch, Kapitel 3.2.1.
2 G. E. P. Muller, M. E. Muller und G. Marsaglia beschreiben sie in ACP, Kapitel 3.4.1
|