常见的伪随机数生成器(PRNG)的原理及C语言实现

1. 线性同余生成器(Linear Congruential Generator, LCG)

原理: 线性同余生成器是最简单和最古老的伪随机数生成算法之一。它使用线性同余方程来生成一个伪随机数序列。

公式: Xn+1=(aXn+c)mod  m

  • XXX 是生成的随机数序列。
  • aaa 是乘数。
  • ccc 是增量。
  • mmm 是模数。

C语言实现

#include <stdio.h>

#define MODULUS 2147483648 // 2^31
#define MULTIPLIER 1103515245
#define INCREMENT 12345

static unsigned long seed = 1; // 初始种子

void srandLCG(unsigned long s) {
    seed = s;
}

unsigned long randLCG() {
    seed = (MULTIPLIER * seed + INCREMENT) % MODULUS;
    return seed;
}

int main() {
    srandLCG(123); // 设置种子
    for (int i = 0; i < 10; i++) {
        printf("%lu\n", randLCG());
    }
    return 0;
}

2. 梅森旋转算法(Mersenne Twister)

原理: 梅森旋转算法是一种更复杂但质量更好的伪随机数生成算法。它以梅森素数(一个形如2n−12^n-12n−1的素数)为基础,有极长的周期和良好的随机性。

#include <stdio.h>

#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL
#define UPPER_MASK 0x80000000UL
#define LOWER_MASK 0x7fffffffUL

static unsigned long mt[N]; // 624个字的状态向量
static int mti = N + 1; // mt[N] + 1 意味着 mt[N] 未初始化

void init_genrand(unsigned long s) {
    mt[0] = s & 0xffffffffUL;
    for (mti = 1; mti < N; mti++) {
        mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
        mt[mti] &= 0xffffffffUL;
    }
}

unsigned long genrand_int32(void) {
    unsigned long y;
    static unsigned long mag01[2] = {0x0UL, MATRIX_A};
    if (mti >= N) {
        int kk;
        if (mti == N + 1)
            init_genrand(5489UL); // 默认种子
        for (kk = 0; kk < N - M; kk++) {
            y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1UL];
        }
        for (; kk < N - 1; kk++) {
            y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
            mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
        }
        y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
        mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1UL];
        mti = 0;
    }
    y = mt[mti++];
    y ^= (y >> 11);
    y ^= (y << 7) & 0x9d2c5680UL;
    y ^= (y << 15) & 0xefc60000UL;
    y ^= (y >> 18);
    return y;
}

int main() {
    init_genrand(1234); // 设置种子
    for (int i = 0; i < 10; i++) {
        printf("%lu\n", genrand_int32());
    }
    return 0;
}

3. Xorshift 算法

原理: Xorshift 算法是一种高效的伪随机数生成算法,通过对数的位进行异或和移位操作来生成随机数。

C语言实现

#include <stdio.h>

static unsigned long x = 123456789;
static unsigned long y = 362436069;
static unsigned long z = 521288629;
static unsigned long w = 88675123;

unsigned long xorshift() {
    unsigned long t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
}

int main() {
    for (int i = 0; i < 10; i++) {
        printf("%lu\n", xorshift());
    }
    return 0;
}

以上是几种常见的伪随机数生成算法及其在C语言中的实现。根据具体的应用需求,可以选择合适的PRNG算法来生成随机数。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值