Ich suche nach einer generischen, wiederverwendbaren Möglichkeit, a std::vector
in C ++ zu mischen . So mache ich das derzeit, aber ich denke, es ist nicht sehr effizient, da es ein Zwischenarray benötigt und den Elementtyp kennen muss (DeckCard in diesem Beispiel):
srand(time(NULL));
cards_.clear();
while (temp.size() > 0) {
int idx = rand() % temp.size();
DeckCard* card = temp[idx];
cards_.push_back(card);
temp.erase(temp.begin() + idx);
}
rand()
, es sind bessere RNG-APIs verfügbar (Boost.Random oder 0x<random>
).Antworten:
Ab C ++ 11 sollten Sie Folgendes bevorzugen:
Live example on Coliru
Stellen Sie sicher, dass Sie dieselbe Instanz
rng
während mehrerer Aufrufe wiederverwenden ,std::shuffle
wenn Sie beabsichtigen, jedes Mal unterschiedliche Permutationen zu generieren!Wenn Sie möchten, dass Ihr Programm bei jeder Ausführung unterschiedliche Shuffles-Sequenzen erstellt, können Sie den Konstruktor der Zufalls-Engine mit der Ausgabe von
std::random_device
:Für C ++ 98 können Sie Folgendes verwenden:
quelle
std::random_shuffle
.std::random_shuffle
wenn dies ein Problem darstellt.random_shuffle
. Dieses Verhalten ist normal und beabsichtigt.#include <algorithm>
http://www.cplusplus.com/reference/algorithm/shuffle/
quelle
std::random_device
?Zusätzlich zu dem, was @Cicada gesagt hat, sollten Sie wahrscheinlich zuerst säen,
Per @ FredLarsons Kommentar:
Also YMMV.
quelle
random_shuffle()
die Implementierung definiert, sodass sie möglicherweise überhaupt nicht verwendet wirdrand()
. Dannsrand()
hätte das keine Wirkung. Darauf bin ich schon einmal gestoßen.random_shuffle
ist die Implementierung definiert, wie @Fred Zufallszahlen generiert. Dies bedeutet, dass bei Ihrer Implementierungrand()
(und damit srand () funktioniert), bei meiner jedoch etwas völlig anderes verwendet werden kann, was bedeutet, dass ich bei meiner Implementierung auch mit srand jedes Mal, wenn ich das Programm ausführe, die gleichen Ergebnisse erhalte.Wenn Sie Boost verwenden, können Sie diese Klasse verwenden (
debug_mode
ist auf gesetztfalse
, wenn Sie möchten, dass die Randomisierung zwischen der Ausführung vorhersehbar ist, müssen Sie sie setzentrue
):Dann können Sie es mit diesem Code testen:
quelle
std::random_device
?Es kann noch einfacher sein, das Säen kann gänzlich vermieden werden:
Dies erzeugt jedes Mal, wenn das Programm ausgeführt wird, eine neue Zufallswiedergabe. Ich mag diesen Ansatz auch wegen der Einfachheit des Codes.
Dies funktioniert , weil alles , was wir brauchen für
std::shuffle
eine istUniformRandomBitGenerator
, die Anforderungenstd::random_device
erfüllt.Hinweis: Wenn Sie wiederholt mischen, ist es möglicherweise besser, die
random_device
in einer lokalen Variablen zu speichern :quelle
random_device
...random_device
wurde entwickelt, um nur einmal aufgerufen zu werden, um PRNGs zu säen, und nicht, um immer wieder aufgerufen zu werden (was die zugrunde liegende Entropie schnell erschöpfen und dazu führen kann, dass sie zu einem suboptimalen Generierungsschema wechselt)Abhängig von dem Standard, dem Sie folgen müssen (C ++ 11 / C ++ 14 / C ++ 17), bietet diese Seite "cppreference" ziemlich gute Beispiele: https://en.cppreference.com/w/cpp/algorithm/ random_shuffle .
quelle