随机数产生方法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

伪随机数的产生,现在用得较多的是“线性同余法"

就是下面这个式子

R(n+1) = [R(n) * a + b] mod c

为使随机数分布尽量均匀,a、b 均为质数, c 一般取值域内的最大值(mod 是求余数)

从这个式了可以看出,每次产生的随机数都跟上一次产生的数有关系,那么,第一个数是怎么来的呢?这就是线性同余法中必须用的的”种子",也就是说,给定某个种子后,所产生的随机数序列是固定的,在计算机编程中,一般使用系统时间来初始化种子,就是前面代码中的srand((unsigned)time(NULL)); 这一句了。因为每次运行程序的时间肯定不一样,所以产生散列肯定也不一样,从而达到“随机”的目的。

a,b,c 的取值我用的是a=3373, b=1, c=32768

下面的两个子程序是我在我的项目(S7-200 226)中产生随机的系统编号用的,因为我的编号中只有4位数采用了随机数,所以下面的程序中用的是整型,最大范围为32767。如果需要更宽范围的随机数,可以采用双字类型,并适当修改程序,代码很简单,就是将上面那个表达式用S7-200 的指令表示出来就行了。

这两个子程序是从MicroWIN V4.0 中导出来的,可以将它们用文本编辑器保存

为AWL 文件后直接导入MicroWIN。

使用时在第一个扫描周期调用Srand 初始种子,需要随机数的地方调用Random Random 有了个最大范围参数,可以限制生成的随机数的最大范围,比如我只需要4位随机数,所以一般这样调用CALL Random, 10000, vw0,生成的数就在0-9999 范围内

下面是代码:

SUBROUTINE_BLOCK Srand:SBR17

TITLE=初始化随机数种子

//

// 直接使用系统时钟的分秒来作为种子

VAR_OUTPUT

seed:WORD;

END_VAR

BEGIN

Network 1

LD SM0.0

TODR VB1990

Network 2

LD SM0.0

BTI VB1994, AC1

SLW AC1, 8

BTI VB1995, AC3

+I AC3, AC1

MOVW AC1, LW0

END_SUBROUTINE_BLOCK

SUBROUTINE_BLOCK Random:SBR16

TITLE=随机数发生器

//

// 线性同余法获取伪随机数,范围:0~32767

//

// seed = (seed * 3373 + 1) % 32768; //

VAR_INPUT

wMax:WORD; // 最大范围

END_VAR

VAR_OUTPUT

wOut:WORD;

END_VAR

BEGIN

Network 1

// wSeed * 3373 + 1 => AC1

LD SM0.0

ITD VW1940, AC1

*D 3373, AC1

INCD AC1

Network 2

// AC1 mod 32768 => wSeed

LD SM0.0

MOVD AC1, AC3

/D +32768, AC3

*D 32768, AC3

-D AC3, AC1

DTI AC1, VW1940

Network 3

// wSeed / 32768 * wMax => wOut LD SM0.0

DTR AC1, AC1

/R 32768.0, AC1

ITD LW0, AC3

DTR AC3, AC3

*R AC3, AC1

ROUND AC1, AC1

DTI AC1, LW2

END_SUBROUTINE_BLOCK

相关文档
最新文档