随机数使用场景
主要适用于伪随机环境下的同步计算:
场景一:服务端要校验客户端数据,服务端和客户端公用一个随机数种子,使每一步产生相同的随机数,服务端校验客户端产生的结果;
场景二:不同服务器环境下对于相同种子的伪随机同步;
场景三:……
参考文献
http://blog.skyoung.org/2013/08/27/generate-random-number/ http://blog.csdn.net/hackmind/article/details/6388044 http://blog.csdn.net/hackmind/article/details/7798769
核心思想
主要是利用线性同余思想来进行随机数生成设计,摒弃平台间的参数不同造成相同种子产生伪随机数值不一样的情况。
线性同余容易理解,容易实现,而且速度快。算法数学上基于公式:X(n+1) = (a * X(n) + c) % m,其中:
模m, m > 0
系数a, 0 < a < m
增量c, 0 <= c < m
原始值(种子) 0 <= X(0) < m
参数c, m, a比较敏感,或者说直接影响了伪随机数产生的质量,不同的编译环境对参数取值均不一致,在WiKi上已有资料。
一些代码
/** * @brief 同步伪随机类,主要跨平台根据同样的seed计算出一致的随机结果 * * @warn 暂时没考虑多线程场景 */ class SyncRand { //算法数学模型 X(n+1) = (a * X(n) + c) % m ,参数选取参考gcc #define SR_A ((uint64_t)1103515245) #define SR_C ((uint64_t)12345) #define SR_M ((uint64_t)1<<32) public: SyncRand(uint64_t seed) : Xn(seed) {} ~SyncRand() {} uint32_t rand() { Xn = ((SR_A * Xn + SR_C) % SR_M); return Xn; } private: uint64_t Xn; };
测试用例:
int main() { SyncRand sr(time(NULL)); for (int i = 0; i < 1000000; i++) { printf("%u\n", (sr.rand() % 10000)); } return 0; } //用来查看万分比概率分布 //[xxx]$./test | awk '{a[$1]++}END{for(k in a) print k,a[k]}' | sort -k1 -g
转载文章请注明出处:漫漫路 - lanindex.com