Suche…


Bemerkungen

Die Erzeugung von <random> in C ++ wird vom Header <random> bereitgestellt. Dieser Header definiert Zufallsgeräte, Pseudozufallsgeneratoren und Verteilungen.

Zufällige Geräte geben vom Betriebssystem bereitgestellte Zufallszahlen zurück. Sie sollten entweder zur Initialisierung von Pseudozufallsgeneratoren oder direkt für kryptographische Zwecke verwendet werden.

Pseudozufallsgeneratoren geben basierend auf ihrem Anfangsstart ganzzahlige Pseudozufallszahlen zurück. Der Pseudozufallszahlenbereich umfasst typischerweise alle Werte eines vorzeichenlosen Typs. Alle Pseudo-Zufallsgeneratoren in der Standardbibliothek geben für alle Plattformen die gleichen Zahlen für denselben Anfangswert aus.

Verteilungen verbrauchen Zufallszahlen von Pseudozufallsgeneratoren oder Zufallsvorrichtungen und erzeugen Zufallszahlen mit der erforderlichen Verteilung. Distributionen sind nicht plattformunabhängig und können unterschiedliche Nummern für dieselben Generatoren mit demselben Start-Seed auf verschiedenen Plattformen erzeugen.

Echter Zufallswertgenerator

Um echte Zufallswerte zu erzeugen, die für die Kryptographie verwendet werden können, muss std::random_device als Generator verwendet werden.

#include <iostream>
#include <random>

int main()
{
   std::random_device crypto_random_generator;
   std::uniform_int_distribution<int> int_distribution(0,9);
   
   int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0};
   
   for(int i = 0; i < 10000; i++) {
       int result = int_distribution(crypto_random_generator);
       actual_distribution[result]++;
   }

   for(int i = 0; i < 10; i++) {
       std::cout << actual_distribution[i] << " ";
   }
   
   return 0;
}

std::random_device wird auf dieselbe Weise verwendet wie ein Pseudo-Zufallswertgenerator.

std::random_device kann jedoch im Hinblick auf eine implementierungsdefinierte Pseudozufallszahlen-Engine implementiert werden, wenn eine nicht deterministische Quelle (z. B. ein Hardwaregerät) für die Implementierung nicht verfügbar ist.

Das Erkennen solcher Implementierungen sollte über die entropy Member-Funktion möglich sein (die Null zurückgibt, wenn der Generator vollständig deterministisch ist), aber viele gängige Bibliotheken (sowohl GCCs libstdc ++ als auch LLVMs libc ++) geben immer null zurück, selbst wenn sie qualitativ hochwertige externe Zufälligkeiten verwenden .

Generierung einer Pseudo-Zufallszahl

Ein Pseudo-Zufallszahlengenerator generiert Werte, die basierend auf zuvor generierten Werten geschätzt werden können. Mit anderen Worten: es ist deterministisch. Verwenden Sie keinen Pseudo-Zufallszahlengenerator in Situationen, in denen eine echte Zufallszahl erforderlich ist.

#include <iostream>
#include <random>

int main()
{
   std::default_random_engine pseudo_random_generator;
   std::uniform_int_distribution<int> int_distribution(0, 9);
   
   int actual_distribution[10] = {0,0,0,0,0,0,0,0,0,0};
   
   for(int i = 0; i < 10000; i++) {
       int result = int_distribution(pseudo_random_generator);
       actual_distribution[result]++;
   }

   for(int i = 0; i <= 9; i++) {
       std::cout << actual_distribution[i] << " ";
   }
   
   return 0;
}

Dieser Code erstellt einen Zufallszahlengenerator und eine Verteilung, die mit gleicher Wahrscheinlichkeit Ganzzahlen im Bereich [0,9] generiert. Es zählt dann, wie oft jedes Ergebnis generiert wurde.

Der Vorlagenparameter von std::uniform_int_distribution<T> gibt den Typ der Ganzzahl an, die generiert werden soll. Verwenden Sie std::uniform_real_distribution<T> , um Floats oder Doubles zu generieren.

Verwendung des Generators für mehrere Distributionen

Der Zufallszahlengenerator kann (und sollte) für mehrere Verteilungen verwendet werden.

#include <iostream>
#include <random>

int main()
{
   std::default_random_engine pseudo_random_generator;
   std::uniform_int_distribution<int> int_distribution(0, 9);
   std::uniform_real_distribution<float> float_distribution(0.0, 1.0);
   std::discrete_distribution<int> rigged_dice({1,1,1,1,1,100});
   
   std::cout << int_distribution(pseudo_random_generator) << std::endl;
   std::cout << float_distribution(pseudo_random_generator) << std::endl;
   std::cout << (rigged_dice(pseudo_random_generator) + 1) << std::endl;
   
   return 0;
}

In diesem Beispiel ist nur ein Generator definiert. Anschließend wird ein Zufallswert in drei verschiedenen Verteilungen generiert. Die rigged_dice Verteilung einen Wert zwischen 0 und 5, erzeugt aber fast erzeugt immer ein 5 , weil die Chance ein generieren 5 ist 100 / 105 .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow