利用线性同余法产生随机数进行同步计算

随机数使用场景

主要适用于伪随机环境下的同步计算:

场景一:服务端要校验客户端数据,服务端和客户端公用一个随机数种子,使每一步产生相同的随机数,服务端校验客户端产生的结果;

场景二:不同服务器环境下对于相同种子的伪随机同步;

场景三:……

参考文献

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

Leave a Comment

Your email address will not be published.