c++ - motor - planta electrica para casa
¿Por qué sigo obteniendo el mismo primer dígito mientras he sembrado un generador con el tiempo? (2)
Como se sugiere en los comentarios, el std::random_device proporcionará una fuente superior de material de semilla en comparación con time()
.
Sin embargo, si existe la necesidad de usar una semilla pequeña con un generador lineal congruente, el valor de la semilla se puede expandir para hacer un mejor inicializador. Los generadores lineales son lentos en la redistribución de los bits en el valor semilla, por lo que una pequeña diferencia hará que los pocos valores iniciales estén cerca unos de otros.
La biblioteca estándar proporciona std::seed_seq que expandirá una semilla pequeña a un mejor valor de inicializador:
seed_seq seed({t});
default_random_engine e(seed);
No entiendo por qué sigo obteniendo el mismo 1er dígito cuando ya he sembrado un default_random_engine
con el time(0)
( C ++ Primer me dice que use el time(0)
). ¿Es un problema de mi computadora? (Ubuntu, C ++ 11)
Probé con un compilador en línea y es interesante que obtuve el mismo primer dígito usando gcc
mientras no uso el clang++
.
https://wandbox.org/permlink/kiUg1BW1RkDL8y8c
Código:
#include <iostream>
#include <ctime>
#include <random>
using namespace std;
int main(){
auto t = time(0);
cout << "time: " << t << endl;
default_random_engine e(t);
uniform_int_distribution<int> uniform_dist(0, 9);
cout << "sequence:";
for(int i = 0; i < 10; i++){
cout << uniform_dist(e);
}
cout << endl;
return 0;
}
Resultado:
Como puedes ver, sigo obteniendo 6
como el primer dígito de un número aleatorio, no importa si uso clang++
o g++
para compilar.
Está configurando estados iniciales en su generador aleatorio que son muy similares. Dependiendo de la calidad del generador, esto puede o no resultar en salidas similares. Para ilustrar, he aumentado su muestra para (a) imprimir solo la primera secuencia, ya que eso es lo que nos importa, y (b) imprimir varios resultados de varias resoluciones:
int main(){
auto t = time(0);
cout << "time: " << t << endl;
default_random_engine e(t);
default_random_engine e2(t);
default_random_engine e3(t);
default_random_engine e4(t);
uniform_int_distribution<int> uniform_dist(0, 9);
uniform_int_distribution<int> uniform_dist2(0,999);
uniform_int_distribution<int> uniform_dist3(0,99999);
uniform_int_distribution<int> uniform_dist4(0,9999999);
cout << "sequence: ";
cout << uniform_dist(e) << " " << uniform_dist2(e2) << " " << uniform_dist3(e3) << " " << uniform_dist4(e4);
cout << endl;
return 0;
}
Cuando se ejecuta:
$ ./a.out
time: 1541162210
sequence: 7 704 70457 7070079
$ ./a.out
time: 1541162211
sequence: 7 704 70457 7070157
$ ./a.out
time: 1541162212
sequence: 7 704 70458 7070236
$ ./a.out
time: 1541162213
sequence: 7 704 70459 7070315
$ ./a.out
time: 1541162214
sequence: 7 704 70460 7070393
$ ./a.out
time: 1541162215
sequence: 7 704 70461 7070472
$ ./a.out
time: 1541162216
sequence: 7 704 70461 7070550
$ ./a.out
time: 1541162217
sequence: 7 704 70462 7070629
$ ./a.out
time: 1541162218
sequence: 7 704 70463 7070707
$ ./a.out
time: 1541162219
sequence: 7 704 70464 7070786
Si bien no sé exactamente qué está haciendo esta implementación de generador aleatorio, puedes ver fácilmente que está realizando una transformación muy simple de tu semilla en estado y estado en valores de salida. Como otros comentarios han sugerido, hay mejores generadores aleatorios y mejores semillas. También tenga en cuenta que la calidad varía entre las implementaciones; Visual Studio 2017 no presenta este comportamiento.