伪随机数生成算法——线性同余法

文章介绍了如何使用LCG(线性同余法)生成伪随机数,包括关键参数的选择和算法原理。通过示例代码展示了如何在C语言中实现这一算法,并讨论了确保最大周期的条件,如C和M互质,以及A、C、seed与M的关系等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

获取随机数一般很容易,只需要

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    int i;
    // 使用系统时间作为种子(初始化随机数,用于确定随机数生成器生成随机数序列的起点),确保每次运行产生不同的随机数序列,函数time返回从1970.1.1以来经历的秒数
    srand(time(NULL));
    for (i = 0; i < 10; i++) {
        int random_num = rand();
        printf("%d\n", random_num);
    }

    return 0;
}

本文探讨使用静态随机变量实现伪随机数生成——LCG算法

先给代码(两个文件):

// 文件:main.c
#include <stdio.h>
#include <time.h>
#define N 100
void mysrand(unsigned);
unsigned myrand();

int main() {
    int i, head = 0, reverse = 0;
    mysrand(time(NULL));
    for (i = 0; i < N; i++)
    {
        if (myrand() % 2)  head++;
        else   reverse++;
    }
    printf("%d%d\n", head, reverse);
    return 0;
}
// 文件:rand.c
#define INITIAL_SEED 17
#define MULTIPLIER 25173
#define INCREMENT 13849
#define MODULUS 32767
static unsigned long seed = INITIAL_SEED;  // 种子
unsigned myrand()
{
	seed = (seed * MULTIPLIER + INCREMENT) % MODULUS;
	return seed;  // 0~MODULUS的随机整数
}
void mysrand(unsigned x)
{
	seed = x;  // 用形参x初始化随机数的种子
}

使用static定义静态随机变量可以让seed只被当前文件内的函数使用,不会被其它文件误使用。

该程序使用LCG生成随机数,依据随机数的奇偶性分配数字给printf的四位数的1,23,4位。其中千位与百位的“二位数”代表随机数的偶数次数,十位与个位的“二位数”代表奇数次数。

伪随机数生成算法——线性同余法(LCG Linear Congruential Generator)

式中Xn是伪随机序列,seed是种子变量,M是模数,A是乘数,C是增量。

 

A,C,M的选取可以多种多样,为了方便计算,一般采用M=2^k混合同余法。当M2的幂时,可以用位运算实现模运算,提高计算效率。

M越大,均值越接近(MIN+MAX)/2MINMAX视参数而定),方差越接近1/12

线性同余法的最大周期是M,但一般情况下会小于M。要使周期达到最大,应该满足以下条件

(1)CM互质;(没有共同的质因子,确保在一次完整的循环中,所有取值都能够被覆盖到)

(2)M的所有质因子的积能整除A-1(确保在一次完整的循环中,所有取值都能够被生成,以避免出现周期缩短的情况。)

(3)M4的倍数,则A-1也是;(为了避免周期缩短)

(4)A,C,seed都比M小;(确保生成的伪随机数在取模运算时不超过上限M)

(5)A,C是正整数。(有本事你不用正整数)

    比如:设M=16,A=5,C=3,seed=2(1)C,M互质,(2)M的所有质因子「也就是2」的积「也就是2」可以整除A-1「也就是4」,(3)(4)(5)过于显然,略。满足条件。

 条件不满足的情况(4,5太简单了就不举例了)

如需证明过程,可参考文献:

[1]张广强,张小彩.混合线性同余发生器的周期分析[J].商丘师范学院学报,2007,(6): 40-42

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值