int GRASP::pickARandomNumberBetween(int begin, int end){ typedef boost::mt19937 RNGType; RNGType rng; rng.seed(std::random_device()()); boost::uniform_int<> begin_to_end( begin, end ); boost::variate_generator< RNGType, boost::uniform_int<> > dice(rng, begin_to_end); return dice(); }
inline bool random_rng_k(const RNGType &, const std::string &filename) { using result_type = typename RNGType::result_type; using key_type = typename RNGType::key_type; std::ifstream kat(filename); mckl::Vector<result_type> k; result_type x; while (kat >> x) k.push_back(x); kat.close(); RNGType rng; mckl::Vector<result_type> r(k.size()); mckl::rand(rng, k.size(), r.data()); key_type kk; for (std::size_t i = 0; i != kk.size(); ++i) kk[i] = static_cast<typename key_type::value_type>(rng()); rng.seed(kk); key_type rk = rng.key(); return k.size() != 0 && k == r && kk == rk; }
void RNG :: Randomise( int n ) { mNeedRandomise = false; mLastSeed = n; theGen.seed( n ); theGen(); }
namespace DMK { //---------------------------------------------------------------------------- // Global random number generator //---------------------------------------------------------------------------- typedef boost::minstd_rand RNGType; static RNGType theGen; //---------------------------------------------------------------------------- // Default RNG seed //---------------------------------------------------------------------------- int RNG::mLastSeed = 350891; bool RNG::mNeedRandomise = true; //---------------------------------------------------------------------------- // Randomise generator with value N //---------------------------------------------------------------------------- void RNG :: Randomise( int n ) { mNeedRandomise = false; mLastSeed = n; theGen.seed( n ); theGen(); } //---------------------------------------------------------------------------- // Ensure RNG is randomised //---------------------------------------------------------------------------- void RNG::Randomise() { if ( mNeedRandomise ) { Randomise( mLastSeed ); } } //---------------------------------------------------------------------------- // Get random number in range [begin,end) - not used much in current code // which uses distributions. //---------------------------------------------------------------------------- int RNG :: Random( int begin, int end ) { if ( mNeedRandomise ) { Randomise( mLastSeed ); } if ( begin >= end ) { throw Exception( "Invalid random number range" ); } int n = end - begin; const int bsize = INT_MAX / n; int r; do { r = theGen() / bsize; } while( r >= n ); return begin + r; } //---------------------------------------------------------------------------- // Get raw random number. //---------------------------------------------------------------------------- int RNG :: Random() { if ( mNeedRandomise ) { Randomise( mLastSeed ); } return theGen(); } //---------------------------------------------------------------------------- // Get last number used to seed RNG. //---------------------------------------------------------------------------- int RNG :: GetSeed() { return mLastSeed; } //---------------------------------------------------------------------------- // Implementation of trianguular distribution // These should probably be templated //---------------------------------------------------------------------------- struct TDImpl { typedef boost::triangle_distribution <double> DistType; typedef boost::variate_generator<RNGType&, DistType> GenType; typedef boost::generator_iterator<GenType> IterType; GenType mGen; IterType mIter; TDImpl( double begin, double mode, double end ) : mGen( theGen, DistType( begin, mode, end ) ), mIter( &mGen ) { } double Next() { return * mIter++; } }; //---------------------------------------------------------------------------- // Implementation of uniform distribution //---------------------------------------------------------------------------- struct UDImpl { typedef boost::uniform_real <double> DistType; typedef boost::variate_generator<RNGType&, DistType> GenType; typedef boost::generator_iterator<GenType> IterType; GenType mGen; IterType mIter; UDImpl( double begin, double end ) : mGen( theGen, DistType( begin, end ) ), mIter( &mGen ) { } double Next() { return * mIter++; } }; //---------------------------------------------------------------------------- // Base virtual dtor //---------------------------------------------------------------------------- Distribution :: ~Distribution() { // nothing } //---------------------------------------------------------------------------- // Triangle distribution uses a mode to skew the distribution //---------------------------------------------------------------------------- TriangleDist :: TriangleDist( double begin, double mode, double end ) : mImpl( new TDImpl( begin, mode, end ) ) { } TriangleDist :: ~TriangleDist() { delete mImpl; } double TriangleDist :: NextReal() { RNG::Randomise(); return mImpl->Next(); } int TriangleDist :: NextInt() { RNG::Randomise(); return int( mImpl->Next() ); } //---------------------------------------------------------------------------- // Uniform distributions spreads values across range //---------------------------------------------------------------------------- UniformDist :: UniformDist( double begin, double end ) : mImpl( new UDImpl( begin, end ) ) { } UniformDist :: ~UniformDist() { delete mImpl; } double UniformDist ::NextReal() { RNG::Randomise(); return mImpl->Next(); } int UniformDist ::NextInt() { RNG::Randomise(); return int( mImpl->Next() ); } //---------------------------------------------------------------------------- } // namespace