std::mt19937 Clase en C++

La clase std::mt19937 (desde C++11) es un generador de números pseudoaleatorios muy eficiente y se define en un archivo de encabezado aleatorio. Produce números pseudoaleatorios de 32 bits utilizando el conocido y popular algoritmo denominado Mersenne twister. La clase std::mt19937 es básicamente un tipo de clase std::mersenne_twister_engine. 

typedef mersenne_twister_engine<uint_fast32_t,
 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253>
 mt19937;

Sintaxis:

mt19937 mt1(seed_value);

Aquí mt1 es una instancia de la clase mt19937 y se necesita un valor inicial para generar una secuencia completa.

Importancia del nombre mt19937 

mt19937 significa mersenne twister con un período largo de 2 19937 – 1, lo que significa que mt19937 produce una secuencia de enteros de 32 bits que solo se repite después de que se haya generado 2 19937 – 1 número.

Similitudes entre mt19937 y rand() y srand():

El std::mt19937 hace dos cosas:

  • Cuando se crea una instancia de un objeto std::mt19937, toma un argumento que se usa para generar un valor semilla (como srand()).
  • Al usar operator(), genera un número aleatorio (como rand()).

A continuación se muestra el ejemplo para demostrar las similitudes:

C++

// C++ program for demonstrating 
// similaritites
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
  
int main()
{
  // Initializing the sequence 
  // with a seed value
  // similar to srand()
  mt19937 mt(time(nullptr)); 
  
  // Printing a random number
  // similar to rand()
  cout << mt() << '\n'; 
  return 0;
}
Producción

3529725061

Al ser un tipo de clase std::mersenne_twister_engine, tiene las mismas funciones de miembro que hace mersenne_twister_engine. Aquí está la lista de algunas funciones importantes de los miembros:

1. (constructor): construye el objeto mt19937. Toma un valor inicial del tipo de resultado o un objeto de secuencia inicial (similar a la función srand()).

Ejemplo :

C++

// C++ program to implement 
// the above concept
  
// This header file is 
// for time
#include <ctime> 
#include <iostream>
#include <random>
using namespace std;
  
int main()
{
  // Using the constructor to
  // initialize with a seed value
  mt19937 mt(time(nullptr)); 
  
  // Operator() is used to 
  // generate random numbers
  cout << mt() << '\n';
  return 0;
}
Producción

3529725061

2. min(): devuelve el valor mínimo que puede devolver operator() (que es cero).

Ejemplo:

C++

// C++ program for the 
// min()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
  
// Driver code
int main()
{
  // Initializing mt19937
  // object
  mt19937 mt(time(nullptr));
  
  // Prints the minimum value 
  // which is 0
  cout << "the minimum integer it can generate is " << 
           mt.min() << endl; 
  return 0;
}
Producción

the minimum integer it can generate is 0

3. max(): devuelve el valor máximo que puede devolver operator() (que es 2 32 – 1 = 4294967295)

Ejemplo :

C++

// C++ program to demonstrate 
// max()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
  
// Driver code
int main()
{
  // Initializing mt19937
  // object
  mt19937 mt(time(nullptr)); 
    
  // Prints the maximum value
  // which is 4294967295
  cout << "mt19937 can generate random numbers upto " << 
           mt.max() << endl; 
  return 0;
}
Producción

mt19937 can generate random numbers upto 4294967295

4. seed(): reinicializa el valor inicial del objeto tomando un valor inicial del tipo de resultado o tomando un objeto de secuencia inicial.

Ejemplo :

C++

// C++ program to demonstrate
// seed()
#include <iostream>
#include <random>
using namespace std;
  
// Driver code
int main()
{
  // Defining the 
  // mt19937 object
  mt19937 mt; 
    
  // Initializing a random 
  // sequence with a seed value
  mt.seed(45218965); 
    
  cout << "some random numbers generated by mt19937 are:" << 
           endl;
    
  for (int i = 5; i > 0; i--) 
  {
    cout << mt() << ' ';
  }
  return 0;
}
Producción

some random numbers generated by mt19937 are:
3334444225 240363925 3350157104 146869560 639267854

5. operator(): genera enteros pseudoaleatorios (similar a la función rand()).

Ejemplo:

C++

// C++ program to demonstrate
// operator()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
  
// Driver code
int main()
{
  // Initializing mt19937
  // object
  mt19937 mt(time(nullptr));
    
  for (int i = 0; i < 5; i++) 
  {
    // operator() is used to
    // generate random numbers
    cout << mt() << ' '; 
  }
  return 0;
}
Producción

3529725061 3019704141 2006641117 725527349 3631905871

También hay funciones que no son miembros sobrecargadas para trabajar con el objeto std::mt19937. Estos son – 

  • operator<<() : está sobrecargado para que podamos imprimir directamente el valor generado por el objeto mt19937 en el flujo de salida.
  • operator>>() : se utiliza para extraer el valor inicial de la entrada.

Aquí hay un ejemplo simple para generar un número pseudoaleatorio tomando un valor inicial del usuario: 

Usando operator<<() y operator>>() :

Ejemplo :

C++

// C++ program to demonstrate 
// operator>>() and <<operator()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
  
// Driver code
int main()
{
  mt19937 mt;
  cout << "enter a integer to begin" << 
           endl;
    
  // operator>>() is used to get 
  // a seed value from the user
  cin >> mt; 
    
  // <<operator() is used to print 
  // the random integer
  cout << "a random number " << 
           mt() << " is generated";
    
  return 0;
}
Producción

enter a integer to begin
a random number 3499211612 is generated

¿Por qué usar mt19937 en lugar de rand()?

Aunque la función rand() se puede usar en un rango pequeño, es ineficiente para generar números aleatorios del mundo real. Una persona cuidadosa puede observar las repeticiones de los números aleatorios generados por rand(), lo cual es muy arriesgado. Mientras que std::mt19937 tiene las siguientes ventajas: 

  1. Tiene un período muy largo en comparación con el rand(). Tomará más tiempo. Si una implementación del tornado de Mersenne pudiera generar 1 000 000 000 (mil millones) de números pseudoaleatorios por segundo, un programa que generara números pseudoaleatorios necesitaría ejecutarse aproximadamente 1,3684 × 105 985 años para repetir la secuencia aleatoria. Por lo tanto, es seguro asumir que un observador nunca adivinará el número.
  2. Muchos generadores de números aleatorios pueden iniciarse simultáneamente con diferentes valores semilla. Aquí hay un ejemplo –

C++

// C++ program to demonstrate
// above approach
#include <iostream>
#include <random>
using namespace std;
  
// Driver code
int main()
{
  mt19937 mt1(10000);
  mt19937 mt2(100000);
  
  cout << mt1() << endl;
  cout << mt2() << endl;
  return 0;
}
Producción

2342776460
1235064505

Publicación traducida automáticamente

Artículo escrito por samufo y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *