1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
#include <random>
#include <algorithm>
#include <vector>
#include <set>
#include <iostream>
#include <iomanip>
// initialize the rng with a seed
// for the same seed, will generate the same sequence of quasi random numbers
std::mt19937 initialize_twister( int seed )
{
static constexpr std::size_t NDISCARD = 1024 ;
std::minstd_rand lcg(seed) ;
lcg.discard(NDISCARD) ;
std::size_t seeds[ std::mt19937::state_size ] ;
std::generate_n( seeds, std::mt19937::state_size, lcg ) ;
std::seed_seq seed_sequence( std::begin(seeds), std::end(seeds) ) ;
std::mt19937 twister { seed_sequence } ; // warm-up
twister.discard(NDISCARD) ; // warm-up
return twister ;
}
// generate n uniformly distributed, unique, random numbers with the rng
std::vector<int> generate_unique( std::mt19937& rng, std::size_t n, int minv, int maxv )
{
std::uniform_int_distribution<int> distr( minv, maxv ) ;
std::set<int> set ;
while( set.size() < n ) set.insert( distr(rng) ) ;
return { set.begin(), set.end() } ;
}
// generate a new quasi random permuatation of the numbers (fisher yates shuffle)
std::vector<int> shuffle( std::vector<int>& seq )
{
static std::mt19937 rng = initialize_twister(1000) ;
std::shuffle( std::begin(seq), std::end(seq), rng ) ;
return seq ;
}
int main()
{
constexpr int N = 2 ;
int seeds[N] { 5678, 111111 };
std::vector<std::mt19937> rngs ; // quasi rngs
for( int s : seeds ) rngs.push_back( initialize_twister(s) ) ;
std::cout << "---------------------------------------------\n" ;
for( auto& twister : rngs ) // for each rng
{
// generate 10 quasi random numbers uniformly distributed in [0,9999]
std::vector<int> seq = generate_unique( twister, 10, 0, 9999 ) ;
// print three quasi random sequences of these numbers
for( int i = 0 ; i < 3 ; ++i )
{
shuffle(seq) ;
for( int v : seq ) std::cout << std::setw(5) << v ;
std::cout << '\n' ;
}
std::cout << '\n' ;
}
}
|