1. Pseudozufallszahlen

Manchmal steht ein Programmierer vor scheinbar einfachen Aufgaben: „Wählen Sie einen zufälligen Film aus einer bestimmten Liste aus“, „wählen Sie einen Lottogewinner“, „mischen Sie die Wiedergabeliste, wenn der Benutzer sein Smartphone schüttelt“, „wählen Sie eine Zufallszahl aus, um eine Nachricht zu verschlüsseln“. usw. In jedem Fall stellt der Entwickler eine logische Frage: Wie erhält man eine Zufallszahl?

Tatsächlich ist es ziemlich schwierig, eine wirklich zufällige Zahl zu erhalten. Tatsächlich ist es so schwierig, dass in manchen Computern spezielle mathematische Coprozessoren eingebaut sind, um Zahlen zu erzeugen, die alle Anforderungen an echte Zufälligkeit erfüllen.

Programmierer haben ihre eigene Lösung gefunden: Pseudozufallszahlen . Pseudozufallszahlen sind eine Art Folge, deren Zahlen zufällig erscheinen. Durch eine sorgfältige Analyse kann ein Experte jedoch bestimmte Muster in der Abfolge finden. Für die Verschlüsselung geheimer Dokumente sind solche Zahlen nicht geeignet, für die Simulation eines Würfelwurfs in einem Spiel reichen sie jedoch aus.

Es gibt viele Algorithmen zum Erzeugen einer Folge von Pseudozufallszahlen. Fast alle generieren die nächste Zufallszahl basierend auf der vorherigen Zahl und einigen zusätzlichen Hilfszahlen.

Dieses Programm zeigt beispielsweise sich 1000nicht wiederholende Zahlen an:

public class Main
{
   public static int a = 41;
   public static int c = 11119;
   public static int m = 11113;
   public static int seed = 1;

   public static int getNextRandom()
   {
     seed = (a * seed + c) % m;
     return seed;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 1000; i++)
     {
       System.out.println(getNextRandom());
     }
   }
}

Wir sprechen hier übrigens nicht von Pseudozufallszahlen. Wir sprechen von einer Folge von Pseudozufallszahlen. Wenn man eine einzelne Zahl betrachtet, kann man nicht sagen, ob sie zufällig ist oder nicht.

Tatsächlich gibt es verschiedene Möglichkeiten, eine Zufallszahl zu erhalten:

public static int getRandomNumber()
{
   return 4; // Here's a random number (we got it by rolling a die)
}

2.Math.random()

In Java Mathverfügt die Klasse über eine spezielle Methode, die eine Zufallszahl zurückgibt. Und wie Sie vielleicht erraten haben, heißt die Methode random. Im Allgemeinen sieht der Aufruf dieser Methode wie folgt aus:

Math.random()

Diese Methode benötigt keine Parameter und gibt eine pseudozufällige reelle Zahl im Bereich von 0bis zurück 1. Die Nummer 1 selbst ist nicht im Sortiment enthalten.

Beispiel:

Code Konsolenausgabe
public class Main
{
   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       System.out.println(Math.random());
     }
   }
}
0.9703753971734451
0.09979423801773157
0.994048474709053
0.2852203204171295
0.13551248551226025
0.3128547131272822
0.5342480554101412
0.6817369932044817
0.1840767788961758
0.06969563435451254

Aber was ist, wenn diese Methode nicht ganz Ihren Anforderungen entspricht? Angenommen, Sie möchten ein Programm schreiben, das das Würfeln eines sechsseitigen Würfels simuliert. Wie erhält man zufällige ganze Zahlen im Bereich 1..6 anstelle von reellen Zahlen im Bereich 0..1?

Es ist eigentlich ziemlich einfach.

Zuerst müssen Sie den Bereich [0, 1)auf abbilden [0, 6). Dazu multiplizieren Sie einfach das von zurückgegebene Ergebnis random()mit 6. Um ganze Zahlen zu erhalten, müssen Sie natürlich aufrunden:

Code Konsolenausgabe
public class Main
{
   public static int getRandomDieNumber()
   {
      return (int) (Math.random() * 6);
   }

   public static void main(String[] args)
   {
      for (int i = 0; i < 10; i++)
      {
         int x = getRandomDieNumber();
         System.out.println(x);
      }
   }
}
5
2
3
3
2
4
1
1
5
0

Das getRandomDieNumber()gibt eine zufällige Ganzzahl im 0..5gesamten Bereich zurück. Aber es wird keine Nummer im Set sein 1, 2, 3, 4, 5, 6. Es wird eine Zahl im Satz sein 0, 1, 2, 3, 4, 5.

Wenn Sie Zahlen in der Menge benötigen 1, 2, 3, 4, 5, 6, fügen Sie einfach eine zu den Zufallszahlen hinzu:

Code Konsolenausgabe
public class Main
{
   public static int getRandomDieNumber()
   {
      return (int) (Math.random() * 6) + 1;
   }

   public static void main(String[] args)
   {
     for (int i = 0; i < 10; i++)
     {
       int x = getRandomDieNumber();
       System.out.println(x);
     }
   }
}
3
2
1
3
6
5
6
1
6
6

Nun, das ist perfekt!



3. RandomKlasse

Java verfügt über eine spezielle RandomKlasse, die eine Folge von Pseudozufallszahlen kapselt. Sie können mehrere Objekte der RandomKlasse erstellen. Jedes dieser Objekte generiert seine eigene Folge von Pseudozufallszahlen.

Dies ist eine super interessante Klasse mit vielen interessanten Methoden. Beginnen wir mit dem Einfachsten.

double nextDouble()

Diese Methode gibt eine zufällige reelle Zahl im Bereich 0.0- zurück 1.0. Es ist der Math.random()Methode sehr ähnlich. Kein Wunder, denn die Math.random()Methode ruft einfach die nextDouble()Methode eines RandomObjekts auf.

float nextFloat()

Diese Methode ist der nextDouble()Methode sehr ähnlich, die zurückgegebene Zufallszahl ist jedoch eine float. Es liegt auch im Bereich 0.0- 1.0. Und wie immer in Java umfasst der Bereich nicht die Zahl 1.0selbst.

Random r = new Random();
float f = r.nextFloat();

int nextInt(int max)

Diese Methode gibt eine zufällige Ganzzahl im Bereich zurück [0, max). 0ist im Sortiment enthalten, maxist es aber nicht.

Mit anderen Worten: Wenn Sie eine Zufallszahl in der Menge erhalten möchten 1, 2, 3, 4, 5, 6, müssen Sie eine zur zurückgegebenen Zufallszahl hinzufügen:

Random r = new Random();
int x = r.nextInt(6) + 1;

int nextInt()

Diese Methode ähnelt der vorherigen, benötigt jedoch keine Parameter. Was ist also der Bereich für seine Rückgabewerte? Von -2 billionbis +2 billion.

Genauer gesagt von -2147483648bis +2147483647.

long nextLong()

Diese Methode ähnelt der nextInt()Methode, der Rückgabewert liegt jedoch irgendwo im gesamten möglichen Bereich von longs.

boolean nextBoolean()

Diese Methode gibt einen Zufallswert zurück boolean: falseoder true. Dies ist sehr praktisch, wenn Sie eine lange Folge zufälliger boolescher Werte benötigen.

void nextBytes(byte[] data)

Diese Methode gibt nichts zurück (da der Rückgabetyp ist void). Stattdessen wird das übergebene Array mit Zufallswerten gefüllt. Dies ist sehr praktisch, wenn Sie einen großen Puffer mit zufälligen Daten benötigen.

double nextGaussian()

Diese Methode gibt eine zufällige reelle Zahl im Bereich 0.0- zurück 1.0. Allerdings sind die Zahlen in diesem Bereich nicht gleichmäßig verteilt. Stattdessen folgen sie einer Normalverteilung .

Werte in der Nähe der Bereichsmitte ( 0.5) treten häufiger auf als Werte an den Enden des Bereichs.

Zufällige Klasse

In unserem Fall liegt der Höhepunkt der Werteverteilung bei0.5