#include "nonstd.h" //LONGLONG #include //time() #ifdef MULTITHREADED #include "threads.h" #endif #ifdef LINUX #include #include #include #endif //adapted from //http://en.wikipedia.org/wiki/Mersenne_twister#Pseudocode //http://my.opera.com/metrallik/blog/2013/04/19/c-class-for-random-generation-with-mersenne-twister-method class RandomGenerator { private: static const unsigned int length=624; static const unsigned int bitMask_32=0xffffffff; static const unsigned int bitPow_31=1<<31; static const unsigned int MAXVALUE=0xffffffff; unsigned int counter; //only used in randomize(). uninitialized is OK #ifdef MULTITHREADED pthread_mutex_t lock; #endif unsigned int *mt; unsigned int idx; public: RandomGenerator(unsigned int seed) { #ifdef MULTITHREADED pthread_mutex_init(&lock,NULL); #endif mt=new unsigned int[length]; setSeed(seed); } inline void setSeed(unsigned int seed) { #ifdef MULTITHREADED pthread_mutex_lock(&lock); #endif idx=0; mt[0]=seed; for(unsigned int i=1;i>30))+i)&bitMask_32; #ifdef MULTITHREADED pthread_mutex_unlock(&lock); #endif } inline unsigned int randomize() { unsigned int seed; #ifdef LINUX int fd=open("/dev/urandom",O_RDONLY); if (fd>=0) { read(fd,&seed,sizeof(seed)); close(fd); } else #endif { counter++; seed=time(NULL); //time (seconds) seed^=counter; //incremented value, possibly randomly initialized seed^=(unsigned int)&counter; //memory address } setSeed(seed); return seed; } inline unsigned int getUint32() { #ifdef MULTITHREADED pthread_mutex_lock(&lock); #endif if (idx==0) gen(); unsigned int y=mt[idx]; idx=(idx+1)%length; #ifdef MULTITHREADED pthread_mutex_unlock(&lock); #endif y^= y>>11; y^=(y<< 7)&2636928640U; y^=(y<<15)&4022730752U; y^= y>>18; return y; } inline double getDouble() // [0,1) { return double(getUint32())/((LONGLONG)(MAXVALUE)+1); } inline void gen() { for(unsigned int i=0;i>1); if(y%2) mt[i]^=2567483615U; } return; } ~RandomGenerator() { delete[] mt; } };