梅森旋转随机算法,C++和Java代码。
C++:
#ifndef _MersenneTwister_H_ #define _MersenneTwister_H_ #include <time.h> #include <stdint.h> #include <math.h> typedef int32_t MS_INT; class MersenneTwister { public: void rseed(MS_INT seed){ if(isInitialized){ return ; } msInit(seed); } int rand(void){ if(isInitialized == false){ return 0; } return msRand(); } public: MersenneTwister(int seed):isInitialized(0){ rseed(seed); } ~MersenneTwister(){ } /* Initialize the generator from a seed */ void msInit(int seed) { MS_INT i; MS_INT p; idx = 0; MT[0] = seed; for (i=1; i < 624; ++i) { /* loop over each other element */ p = 1812433253 * (MT[i-1] ^ (MT[i-1] >> 30)) + i; MT[i] = p & 0xffffffff; /* get last 32 bits of p */ } isInitialized = 1; } /* Extract a tempered pseudorandom number based on the idx-th value, calling ms_generate() every 624 numbers */ MS_INT msRand() { if (!isInitialized) msInit((MS_INT)time(NULL)); if (idx == 0) msGenerate(); MS_INT y = MT[idx]; y = y ^ (y >> 11); y = y ^ ((y << 7) & 2636928640); y = y ^ ((y << 15) & 4022730752); y = y ^ (y >> 18); idx = (idx + 1) % 624; /* increment idx mod 624*/ return y; } /* Generate an array of 624 untempered numbers */ void msGenerate() { MS_INT i, y; for (i = 0; i < 624; ++i) { y = (MT[i] & 0x80000000) + (MT[(i+1) % 624] & 0x7fffffff); MT[i] = MT[(i + 397) % 624] ^ (y >> 1); if (y % 2) { /* y is odd */ MT[i] = MT[i] ^ (2567483615); } } } private: MS_INT MT[624]; MS_INT idx; MS_INT isInitialized; }; #endif
Java:
package com.art.util; public class MersenneTwister { /* Create a length 624 array to store the state of the generator */ private int [] MT = new int[624]; private int idx; private boolean isInitialized = false; /* Initialize the generator from a seed */ private void msInit(int seed) { int i; int p; idx = 0; MT[0] = seed; for (i=1; i < 624; ++i) { /* loop over each other element */ p = 1812433253 * (MT[i-1] ^ (MT[i-1] >> 30)) + i; MT[i] = p & 0xffffffff; /* get last 32 bits of p */ } isInitialized = true; } private int msRand() { if (!isInitialized){ return 0; } if (idx == 0) msRenerate(); int y = MT[idx]; y = y ^ (y >> 11); y = y ^ ((y << 7) & (int)2636928640l); y = y ^ ((y << 15) & (int)4022730752l); y = y ^ (y >> 18); idx = (idx + 1) % 624; /* increment idx mod 624*/ return y; } private void msRenerate() { int i; int y; for (i = 0; i < 624; ++i) { y = (MT[i] & 0x80000000) + (MT[(i+1) % 624] & 0x7fffffff); MT[i] = MT[(i + 397) % 624] ^ (y >> 1); if (y % 2 != 0) { /* y is odd */ MT[i] = MT[i] ^ (int)(2567483615l); } } } //随机种子 public void rseed(int seed){ if(isInitialized){ return ; } msInit(seed); } //随机值 public int rand(){ if(isInitialized == false){ return 0; } return msRand(); } public MersenneTwister(int seed){ rseed(seed); } }