Estoy buscando una forma genérica y reutilizable de barajar un std::vector
en C ++. Así es como lo hago actualmente, pero creo que no es muy eficiente porque necesita una matriz intermedia y necesita saber el tipo de elemento (DeckCard en este ejemplo):
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()
, hay mejores API de RNG disponibles (Boost.Random o 0x<random>
).Respuestas:
Desde C ++ 11 en adelante, debería preferir:
Live example on Coliru
¡Asegúrese de reutilizar la misma instancia de a lo
rng
largo de múltiples llamadas astd::shuffle
si tiene la intención de generar diferentes permutaciones cada vez!Además, si desea que su programa cree diferentes secuencias de mezcla cada vez que se ejecuta, puede sembrar el constructor del motor aleatorio con la salida de
std::random_device
:Para C ++ 98 puede usar:
fuente
std::random_shuffle
.std::random_shuffle
si esto es un problema.random_shuffle
. Este comportamiento es normal e intencionado.#include <algorithm>
http://www.cplusplus.com/reference/algorithm/shuffle/
fuente
std::random_device
?Además de lo que dijo @Cicada, probablemente deberías sembrar primero,
Según el comentario de @ FredLarson:
Entonces YMMV.
fuente
random_shuffle()
está definida por la implementación, por lo que es posible que no se userand()
en absoluto. Entoncessrand()
no tendría ningún efecto. Me he encontrado con eso antes.random_shuffle
usa para generar números aleatorios es la implementación definida. Esto significa que en su implementación usarand()
(y por lo tanto srand () funciona) pero en la mía puede usar algo totalmente diferente, lo que significa que en mi implementación incluso con srand cada vez que ejecuto el programa obtendré los mismos resultados.Si está usando boost , puede usar esta clase (
debug_mode
está configurada enfalse
, si desea que la aleatorización sea predecible entre la ejecución, debe configurarla entrue
):Entonces puedes probarlo con este código:
fuente
std::random_device
?Puede ser incluso más simple, la siembra se puede evitar por completo:
Esto producirá una nueva reproducción aleatoria cada vez que se ejecute el programa. También me gusta este enfoque debido a la simplicidad del código.
Esto funciona porque todo lo que necesitamos
std::shuffle
es unUniformRandomBitGenerator
, cuyos requisitosstd::random_device
cumplen.Nota: si baraja repetidamente, puede ser mejor almacenar el
random_device
en una variable local:fuente
random_device
...random_device
está diseñado para ser llamado solo una vez para sembrar PRNG, no para ser llamado una y otra vez (lo que puede agotar la entropía subyacente rápidamente y hacer que cambie a un esquema de generación subóptimo)Dependiendo del estándar que tenga que seguir (C ++ 11 / C ++ 14 / C ++ 17), esta página "cppreference" proporciona ejemplos bastante buenos: https://en.cppreference.com/w/cpp/algorithm/ random_shuffle .
fuente