Seed-Zufallszahlengenerator in C++
- Konzept von Seed im Zufallszahlengenerator in C++
-
Verwenden Sie die Funktion
srand()
, um den Zufallszahlengenerator in C++ zu starten -
Verwendung der Funktion
time()
zum Seeden des Zufallszahlengenerators in C++ - Seeding des Zufallsgenerators Zu vermeidende Fehler
- Fazit
Programmiersprachen wie C++ erzeugen keine echten Zufallszahlen. Vielmehr erzeugt der Computer mit einer mathematischen Funktion Pseudo-Zufallszahlen.
In diesem Artikel werden das Konzept des Seeds beim Generieren von Zufallszahlen und die Methode zum Bereitstellen von Seed für die Funktion zum Generieren von Zufallszahlen in C++ erläutert.
Konzept von Seed im Zufallszahlengenerator in C++
C++ generiert Folgen von Zufallszahlen mit einem deterministischen Algorithmus. Daher ist die Zahlenfolge eher pseudozufällig als rein probabilistisch.
In diesem Fall fungiert der Seed als Ausgangspunkt für den Algorithmus. Sie sollten nicht davon ausgehen, dass die erste generierte Zahl der Seed ist.
Vielmehr wählt der Algorithmus Zahlen zufällig aus einer Verteilung aus, die der Seed definiert. Wenn Sie dem Algorithmus denselben Startwert bereitstellen, generiert er dieselbe Folge von Pseudozufallszahlen.
Möglicherweise müssen Sie jedoch meistens für jede Ausführung eine andere Folge von Pseudozufallszahlen generieren. In diesem Fall müssen Sie dem Algorithmus bei jeder Ausführung einen anderen Startwert bereitstellen.
Verwenden Sie die Funktion srand()
, um den Zufallszahlengenerator in C++ zu starten
Die Funktion srand()
akzeptiert eine ganze Zahl ohne Vorzeichen als Argument. Es verwendet das Argument, um den Algorithmus zu starten, der die Pseudozufallszahlen generiert.
Syntax:
void srand(unsigned int seed);
Wenn Sie der Funktion srand()
als Argument 1
übergeben, initialisiert sie den Pseudozufallszahlengenerator auf seinen Anfangswert. Der Generator liefert dieselben Ergebnisse wie der letzte Aufruf der Funktion rand()
.
Sehen wir uns ein Beispiel an, das den Pseudozufallszahlengenerator mit einer willkürlichen Zahl, die dem Benutzer als Eingabe entnommen wird, füttert.
Beispielcode:
#include <iostream>
using namespace std;
int main() {
unsigned int seed;
cout << "Enter seed value:\n";
cin >> seed;
srand(seed);
cout << "Successfully seeded the generator\n";
return 0;
}
Ausgabe:
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Enter seed value:
12
Successfully seeded the generator
Verwendung der Funktion time()
zum Seeden des Zufallszahlengenerators in C++
Das Problem bei dem vorherigen Ansatz besteht darin, dass ein Benutzer dieselbe Zahl mehr als einmal eingeben kann. Wenn Sie sicherstellen müssen, dass dem Algorithmus bei jeder Ausführung ein anderer Startwert bereitgestellt wird, verwenden Sie die Funktion time()
, um dem Pseudozufallszahlengenerator einen Startwert bereitzustellen.
Die Funktion time()
in C++ gibt den aktuellen UNIX-Zeitstempel zurück, die Anzahl der Sekunden, die seit 00:00 Uhr am 1. Januar 1970 UTC vergangen sind.
Syntax:
time_t time(time_t* timer);
Die Funktion nimmt ein Argument als Zeiger vom Typ time_t
entgegen. Wenn Sie der Funktion eine Nicht-Null-Referenz als Parameter zur Verfügung stellen, wird ein Objekt vom Typ time_t
auf den Parameter gesetzt, der den aktuellen Zeitstempel enthält.
Der Typ time_t
ist ein Alias des arithmetischen Typs und kann den aktuellen UNIX-Zeitstempelwert enthalten. Es ist effektiv ein vorzeichenloser ganzzahliger Wert.
Beispielcode:
#include <iostream>
using namespace std;
int main() {
srand(time(NULL));
cout << "Successfully seeded the generator\n";
return 0;
}
Beachten Sie, dass der Code NULL
als Argument an die Funktion time()
übergibt. Gemäß dem Code benötigen Sie das Objekt vom Typ time_t
aus keinem Grund.
Ausgabe:
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Successfully seeded the generator
Seeding des Zufallsgenerators Zu vermeidende Fehler
Im Allgemeinen erzeugen Sie eine Folge von Pseudozufallszahlen in einer Schleife in Ihrem Code. Die meisten Leute machen einen häufigen Fehler, indem sie den Generator jedes Mal starten, wenn die Schleife ausgeführt wird.
In einem solchen Fall erhalten Sie wahrscheinlich sich wiederholende Zahlen, da der Generator jedes Mal dieselbe Zahlenfolge erstellt, wenn Sie ihn mit derselben Zahl füttern.
Dies kann auch dann der Fall sein, wenn Sie die Funktion time()
verwenden, um den Zufallsgenerator zu starten, da die Funktion time()
die Anzahl der Sekunden zurückgibt, die seit einem festen Datum in der Vergangenheit vergangen sind.
Andererseits wird die Schleife viel schneller ausgeführt, und daher gibt jeder Aufruf der Funktion time()
den gleichen Wert zurück, bis eine Sekunde vergangen ist. Auf diese Weise werden Sie am Ende denselben Wert an den Generator senden.
Beispielcode:
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 10; i++) {
srand(time(NULL));
cout << rand() << " ";
}
cout << endl;
return 0;
}
Ausgabe:
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454
Der Code setzt den Zufallsgenerator in die Schleife, und die Ausführung führt zehnmal zu derselben Zahl. Sie sollten den Zufallszahlengenerator immer vor der Schleife starten, um diese Falle zu vermeiden.
Sehen wir uns das Beispiel an, in dem der Code den Zufallsgenerator außerhalb der Schleife startet.
Beispielcode:
#include <iostream>
using namespace std;
int main() {
srand(time(NULL));
for (int i = 1; i <= 10; i++) {
cout << rand() << " ";
}
cout << endl;
return 0;
}
Ausgabe:
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
213462937 1076978976 1207347426 8310730 1551061902 266528745 944000672 871831053 1678325834 868781842
Beachten Sie, dass der Code zu einer anderen Zahlenfolge führt.
Fazit
Sie können den Startwert für den Pseudozufallsgenerator bereitstellen, der als Ausgangspunkt für den Algorithmus dient, aber Sie sollten vorsichtig sein, um die Fallstricke zu vermeiden, wie im Artikel beschrieben. Andernfalls kann es zu unerwünschten Ergebnissen kommen.
Mehr über die Funktion rand()
, die nach dem Seeding die Folge von Pseudozufallszahlen generiert, können Sie hier nachlesen.