Je recherche un moyen générique et réutilisable de mélanger un std::vector
en C ++. C'est comme ça que je le fais actuellement, mais je pense que ce n'est pas très efficace car il a besoin d'un tableau intermédiaire et il a besoin de connaître le type d'élément (DeckCard dans cet exemple):
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()
, il existe de meilleures API RNG disponibles (Boost.Random ou 0x<random>
).Réponses:
À partir de C ++ 11, vous devriez préférer:
Live example on Coliru
Assurez-vous de réutiliser la même instance de
rng
tout au long de plusieurs appels àstd::shuffle
si vous avez l'intention de générer des permutations différentes à chaque fois!De plus, si vous voulez que votre programme crée différentes séquences de shuffles à chaque fois qu'il est exécuté, vous pouvez amorcer le constructeur du moteur aléatoire avec la sortie de
std::random_device
:Pour C ++ 98, vous pouvez utiliser:
la source
std::random_shuffle
.std::random_shuffle
si cela pose un problème.random_shuffle
. Ce comportement est normal et intentionnel.#include <algorithm>
http://www.cplusplus.com/reference/algorithm/shuffle/
la source
std::random_device
?En plus de ce que @Cicada a dit, vous devriez probablement commencer par semer,
Selon le commentaire de @ FredLarson:
Alors YMMV.
la source
random_shuffle()
est définie par l'implémentation, elle ne peut donc pas être utiliséerand()
du tout. Celasrand()
n'aurait alors aucun effet. J'ai déjà rencontré ça.random_shuffle
utilise pour générer un nombre aléatoire est défini par l'implémentation. Cela signifie que sur votre implémentation, il utiliserand()
(et donc srand () fonctionne) mais sur le mien, il peut utiliser quelque chose de totalement différent, ce qui signifie que sur mon implémentation, même avec srand, chaque fois que je lance le programme, j'obtiendrai les mêmes résultats.Si vous utilisez boost, vous pouvez utiliser cette classe (
debug_mode
définie surfalse
, si vous voulez que la randomisation soit prévisible entre les exécutions, vous devez la définir surtrue
):Ensuite, vous pouvez le tester avec ce code:
la source
std::random_device
?Cela peut être encore plus simple, l'ensemencement peut être totalement évité:
Cela produira un nouveau mélange à chaque fois que le programme est exécuté. J'aime aussi cette approche en raison de la simplicité du code.
Cela fonctionne parce que tout ce dont nous avons besoin
std::shuffle
est unUniformRandomBitGenerator
, dont les exigencesstd::random_device
répondent.Remarque: en cas de lecture aléatoire répétée, il peut être préférable de stocker le
random_device
dans une variable locale:la source
random_device
random_device
est conçu pour être appelé une seule fois pour semer les PRNG, pour ne pas être appelé encore et encore (ce qui peut épuiser rapidement l'entropie sous-jacente et la faire passer à un schéma de génération sous-optimal)En fonction de la norme à suivre (C ++ 11 / C ++ 14 / C ++ 17), cette page "cppreference" fournit de très bons exemples: https://en.cppreference.com/w/cpp/algorithm/ random_shuffle .
la source