Generador de números aleatorios de semillas en C++

Mohd Mohtashim Nawaz 11 diciembre 2023
  1. Concepto de Semilla en Generador de Números Aleatorios en C++
  2. Use la función srand() para sembrar el generador de números aleatorios en C++
  3. Use la función time() para sembrar el generador de números aleatorios en C++
  4. Errores que se deben evitar al sembrar el generador aleatorio
  5. Conclusión
Generador de números aleatorios de semillas en C++

Los lenguajes de programación como C++ no generan números verdaderamente aleatorios. Más bien, la computadora genera números pseudoaleatorios usando una función matemática.

Este artículo analiza el concepto de semilla en la generación de números aleatorios y el método para proporcionar semilla a la función utilizada para generar números aleatorios en C++.

Concepto de Semilla en Generador de Números Aleatorios en C++

C++ genera secuencias de números aleatorios utilizando un algoritmo determinista. Por lo tanto, la secuencia de números es pseudoaleatoria en lugar de ser puramente probabilística.

En este caso, la semilla actúa como punto de partida del algoritmo. No debe pensar en ello como si el primer número generado fuera la semilla.

Más bien, el algoritmo elige números al azar de una distribución que define la semilla. Si proporciona la misma semilla al algoritmo, generará la misma secuencia de números pseudoaleatorios.

Sin embargo, es posible que necesite generar una secuencia diferente de números pseudoaleatorios para cada ejecución la mayor parte del tiempo. En ese caso, debe proporcionar una semilla diferente al algoritmo cada vez que se ejecuta.

Use la función srand() para sembrar el generador de números aleatorios en C++

La función srand() acepta un entero sin signo como argumento. Utiliza el argumento para generar el algoritmo que genera los números pseudoaleatorios.

Sintaxis:

void srand(unsigned int seed);

Si proporciona 1 como argumento para la función srand(), inicializa el generador de números pseudoaleatorios a su valor inicial. El generador produce los mismos resultados que la última llamada a la función rand().

Veamos un ejemplo que inicia el generador de números pseudoaleatorios con un número arbitrario tomado del usuario como entrada.

Código de ejemplo:

#include <iostream>

using namespace std;

int main() {
  unsigned int seed;
  cout << "Enter seed value:\n";
  cin >> seed;
  srand(seed);
  cout << "Successfully seeded the generator\n";
  return 0;
}

Producción :

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Enter seed value:
12
Successfully seeded the generator

Use la función time() para sembrar el generador de números aleatorios en C++

El problema con el enfoque anterior es que un usuario puede ingresar el mismo número más de una vez. Si necesita asegurarse de que el algoritmo recibe una semilla diferente cada vez que se ejecuta, use la función time() para proporcionar semilla al generador de números pseudoaleatorios.

La función time() en C++ devuelve la marca de tiempo actual de UNIX, el número de segundos transcurridos desde las 00:00 horas del 1 de enero de 1970, UTC.

Sintaxis:

time_t time(time_t* timer);

La función toma como argumento un puntero de tipo time_t. Si proporciona una referencia no nula a la función como parámetro, establece un objeto de tipo time_t en el parámetro que contiene la marca de tiempo actual.

El tipo time_t es un alias del tipo aritmético y puede contener el valor actual de la marca de tiempo UNIX. Es efectivamente un valor entero sin signo.

Código de ejemplo:

#include <iostream>

using namespace std;

int main() {
  srand(time(NULL));
  cout << "Successfully seeded the generator\n";
  return 0;
}

Tenga en cuenta que el código pasa NULL como argumento a la función time(). Según el código, no necesita el objeto de tipo time_t por ningún motivo.

Producción :

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
Successfully seeded the generator

Errores que se deben evitar al sembrar el generador aleatorio

Generalmente, genera una secuencia de números pseudoaleatorios en un bucle en su código. La mayoría de la gente comete un error común al inicializar el generador cada vez que se ejecuta el bucle.

Es probable que obtenga números repetidos en tal caso porque el generador crea la misma secuencia de números cada vez que lo siembra con el mismo número.

Esto puede ser cierto incluso si usa la función time() para inicializar el generador aleatorio, ya que la función time() devuelve la cantidad de segundos transcurridos desde una fecha fija en el pasado.

Por otro lado, el bucle se ejecutará mucho más rápido y, por lo tanto, cada llamada a la función time() seguirá devolviendo el mismo valor hasta que pase un segundo. De esta manera, terminarás sembrando el mismo valor al generador.

Código de ejemplo:

#include <iostream>

using namespace std;

int main() {
  for (int i = 1; i <= 10; i++) {
    srand(time(NULL));
    cout << rand() << " ";
  }
  cout << endl;
  return 0;
}

Producción :

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454 1524491454

El código genera el generador aleatorio dentro del bucle y la ejecución da como resultado el mismo número diez veces. Siempre debe sembrar el generador de números aleatorios antes del bucle para evitar este escollo.

Veamos el ejemplo en el que el código genera el generador aleatorio fuera del bucle.

Código de ejemplo:

#include <iostream>

using namespace std;

int main() {
  srand(time(NULL));
  for (int i = 1; i <= 10; i++) {
    cout << rand() << " ";
  }
  cout << endl;
  return 0;
}

Producción :

mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ g++ seed_example.cc
mohtashim@mohtashim:~/eclipse-workspace/Java2Blog$ ./a.out
213462937 1076978976 1207347426 8310730 1551061902 266528745 944000672 871831053 1678325834 868781842

Observe que el código da como resultado una secuencia diferente de números.

Conclusión

Puede proporcionar la semilla al generador pseudoaleatorio que actúa como punto de partida para el algoritmo, pero debe tener cuidado para evitar el escollo, como se explica en el artículo. De lo contrario, puede dar lugar a resultados no deseados.

Puede leer más sobre la función rand() que genera la secuencia de números pseudoaleatorios después de la inicialización aquí.

Artículo relacionado - C++ Random