I rot all das Zeug oben, über 40 andere Seiten mit c ++ darin wie dieser und das beobachtete Video von Stephan T. Lavavej „STL“
und war immer noch nicht sicher , wie Zufallszahlen funktionieren in der Praxis , damit ich einen vollen Sonntag nahm , um herauszufinden , Worum geht es und wie es funktioniert und verwendet werden kann.
Meiner Meinung nach hat STL Recht damit, "srand nicht mehr zu verwenden", und er hat es im Video 2 gut erklärt . Er empfiehlt außerdem:
a) void random_device_uniform()
- für verschlüsselte Erzeugung, aber langsamer (aus meinem Beispiel)
b) die Beispiele mit mt19937
- schneller, Fähigkeit, Samen zu erstellen, nicht verschlüsselt
Ich habe alle beanspruchten C ++ 11-Bücher herausgezogen, auf die ich Zugriff habe, und festgestellt, dass deutsche Autoren wie Breymann (2015) immer noch einen Klon von verwenden
srand( time( 0 ) );
srand( static_cast<unsigned int>(time(nullptr))); or
srand( static_cast<unsigned int>(time(NULL))); or
nur mit <random>
statt <time> and <cstdlib>
#includings - also sei vorsichtig, nur aus einem Buch zu lernen :).
Bedeutung - das sollte seit c ++ 11 nicht mehr verwendet werden, weil:
Programme benötigen häufig eine Zufallszahlenquelle. Vor dem neuen Standard stützten sich sowohl C als auch C ++ auf eine einfache C-Bibliotheksfunktion namens rand. Diese Funktion erzeugt pseudozufällige Ganzzahlen, die gleichmäßig im Bereich von 0 bis zu einem systemabhängigen Maximalwert von mindestens 32767 verteilt sind. Die Rand-Funktion weist mehrere Probleme auf: Viele, wenn nicht die meisten Programme benötigen Zufallszahlen in einem anderen Bereich als dem eine von rand produziert. Einige Anwendungen erfordern zufällige Gleitkommazahlen. Einige Programme benötigen Zahlen, die eine ungleichmäßige Verteilung widerspiegeln. Programmierer führen häufig Nicht-Zufälligkeit ein, wenn sie versuchen, den Bereich, den Typ oder die Verteilung der von Rand generierten Zahlen zu transformieren. (Zitat aus Lippmans C ++ Primer fünfte Ausgabe 2012)
Ich fand schließlich die beste Erklärung aus 20 Büchern in Bjarne Stroustrups neueren - und er sollte sich damit auskennen - in "Eine Tour durch C ++ 2019", "Programmierprinzipien und Übung mit C ++ 2016" und "The C ++ Programming Language 4th Edition" 2014 "und auch einige Beispiele in" Lippmans C ++ Primer fünfte Ausgabe 2012 ":
Und es ist wirklich einfach, weil ein Zufallszahlengenerator aus zwei Teilen besteht:
(1) einer Engine, die eine Folge von Zufalls- oder Pseudozufallswerten erzeugt. (2) eine Verteilung, die diese Werte in eine mathematische Verteilung in einem Bereich abbildet.
Trotz der Meinung von Microsofts STL schreibt Bjarne Stroustrups:
In bietet die Standardbibliothek Zufallszahlen-Engines und -Verteilungen (§24.7). Verwenden Sie standardmäßig die default_random_engine, die für eine breite Anwendbarkeit und niedrige Kosten ausgewählt wurde.
Das void die_roll()
Beispiel stammt von Bjarne Stroustrups - eine gute Idee, mit der Engine und Distribution generiert werden using
(mehr dazu hier) .
Um die Zufallszahlengeneratoren, die von der Standardbibliothek hier bereitgestellt werden, in der Praxis nutzen zu können, wurde <random>
hier ein ausführbarer Code mit verschiedenen Beispielen auf das Mindeste reduziert, was hoffentlich Zeit und Geld für Sie sicher macht:
#include <random> //random engine, random distribution
#include <iostream> //cout
#include <functional> //to use bind
using namespace std;
void space() //for visibility reasons if you execute the stuff
{
cout << "\n" << endl;
for (int i = 0; i < 20; ++i)
cout << "###";
cout << "\n" << endl;
}
void uniform_default()
{
// uniformly distributed from 0 to 6 inclusive
uniform_int_distribution<size_t> u (0, 6);
default_random_engine e; // generates unsigned random integers
for (size_t i = 0; i < 10; ++i)
// u uses e as a source of numbers
// each call returns a uniformly distributed value in the specified range
cout << u(e) << " ";
}
void random_device_uniform()
{
space();
cout << "random device & uniform_int_distribution" << endl;
random_device engn;
uniform_int_distribution<size_t> dist(1, 6);
for (int i=0; i<10; ++i)
cout << dist(engn) << ' ';
}
void die_roll()
{
space();
cout << "default_random_engine and Uniform_int_distribution" << endl;
using my_engine = default_random_engine;
using my_distribution = uniform_int_distribution<size_t>;
my_engine rd {};
my_distribution one_to_six {1, 6};
auto die = bind(one_to_six,rd); // the default engine for (int i = 0; i<10; ++i)
for (int i = 0; i <10; ++i)
cout << die() << ' ';
}
void uniform_default_int()
{
space();
cout << "uniform default int" << endl;
default_random_engine engn;
uniform_int_distribution<size_t> dist(1, 6);
for (int i = 0; i<10; ++i)
cout << dist(engn) << ' ';
}
void mersenne_twister_engine_seed()
{
space();
cout << "mersenne twister engine with seed 1234" << endl;
//mt19937 dist (1234); //for 32 bit systems
mt19937_64 dist (1234); //for 64 bit systems
for (int i = 0; i<10; ++i)
cout << dist() << ' ';
}
void random_seed_mt19937_2()
{
space();
cout << "mersenne twister split up in two with seed 1234" << endl;
mt19937 dist(1234);
mt19937 engn(dist);
for (int i = 0; i < 10; ++i)
cout << dist() << ' ';
cout << endl;
for (int j = 0; j < 10; ++j)
cout << engn() << ' ';
}
int main()
{
uniform_default();
random_device_uniform();
die_roll();
random_device_uniform();
mersenne_twister_engine_seed();
random_seed_mt19937_2();
return 0;
}
Ich denke, das summiert sich auf alles und wie gesagt, ich habe eine Menge gelesen und Zeit gebraucht, um diese Beispiele zu destillieren. Wenn Sie weitere Informationen zur Zahlengenerierung haben, freue ich mich, dies per PM oder im Kommentarbereich zu erfahren und wird es bei Bedarf hinzufügen oder diesen Beitrag bearbeiten. Bool