与彩票调度程序的LCG相比,更好的(伪)随机数发生器是什么?

我想设计一个彩票调度器,我需要一个非常好的(伪)随机数发生器,类似于LCG,但我想知道是否还有其他更好的选择? 我特意寻找用C编写的随机生成器。

LCG代码:

unsigned long lcg_rand(unsigned long a) { return (a * 279470273UL) % 4294967291UL; } 

另外我想知道srand()可以用于此目的还是不准确?

如果你需要简单但不错的质量,我会使用64位LCG的高32位(或更少),可能还有一个应用于输出的回火function。 这样做时,我复制了Mersenne Twister中使用的回火function。 我不建议实际使用Mersenne Twister,因为它比其他PRNG具有更多的复杂性和内部状态而没有明显更好的品质。

以下是一些示例代码:

 static uint32_t temper(uint32_t x) { x ^= x>>11; x ^= x<<7 & 0x9D2C5680; x ^= x<<15 & 0xEFC60000; x ^= x>>18; return x; } uint32_t lcg64_temper(uint64_t *seed) { *seed = 6364136223846793005ULL * *seed + 1; return temper(*seed >> 32); } 

Mersenne Twister是一种选择。 另一种选择是使用随机减去

C rand()函数的大多数实现都使用LGC的变体。 rand() ,就像任何计算机化的随机生成器一样,并不是真正随机的,它只是伪随机的。 使用srand()可以改善随机性,但不能使其完美。 它取决于srand()使用的种子的变化和随机性。 例如,如果在srand()使用相同的相同种子n次调用rand() n次,结果将是相同的。 但是如果你每次都调用srand(clock()) (并且调用之间经过的时间大于clock()的ticks周期),那么你将拥有一个改进的随机生成器。

这是一个简单的代码示例,其中使用了clock()和支持函数NotRecentlyUsed() (对于minmax的小样本):

 #include  #define _UNIQUE_ int randomGenerator(int min, int max); int NotUsedRecently (int number); int main(void) { int i=0; for(i=0;i<1000;i++) { printf("%d,\t", randomGenerator(0, 20)); if(i%20 == 0) printf("\n"); } getchar(); return 0; } ////////////////////////////////////////////////////// //generates pseudo random numbers between min and max //If it is desired to use this without a guarantee of uniqueness //for a specified span of values, un-define _UNIQUE_ // int randomGenerator(int min, int max) { int random, trying; trying = 1; while(trying) { srand(clock()); random = (rand()/32767.0)*(max+1); ((random >= min) #ifdef _UNIQUE_ && NotUsedRecently(random) #endif ) ? (trying = 0) : (trying = 1); } return random; } //This function is used to guarantee that a span of n generated values //will not be the same. To adjust the span, change the index in //static int recent[n]; Note: it is required that n < (max-min) //otherwise an infinite loop will occur int NotUsedRecently (int number) { static int recent[20];//Use No greater value for index than max - min int i,j; int notUsed = 1; for(i=0;i<(sizeof(recent)/sizeof(recent[0]));i++) (number != recent[i]) ? (notUsed==notUsed) : (notUsed=0, i=(sizeof(recent)/sizeof(recent[0]))); if(notUsed) { for(j=(sizeof(recent)/sizeof(recent[0]));j>1;j--) { recent[j-1] = recent[j-2]; } recent[j-1] = number; } return notUsed; }