George Marsaglia的随机数生成器

2010年10月5日

Marsaglia使用32位无符号整数,因此所有算术都是模232,这是C通过简单地溢出寄存器实现的,但我们必须显式调用; 注意,虽然在c(c)变量为模28Bit操作在C语言中的表达比Scheme更简洁,而且似乎工作得更快,请原谅我的双关语。这个使随机数生成器的状态变量私有化,而不是像C程序中那样全局化:

(定义mwc#f)
(定义shr3#f)
(定义连接#f)
(定义fib#f)
(定义亲吻#f)
(定义lfib4#f)
(定义swb#f)
(定义uni#f)
(定义vni#f)
(定义可设置#f)

(让(z 362436069)(w 521288629)(jsr 123456789)
(jcong 380116160)(甲224466889)(乙7584631)
(t(标记向量2560))(x 0)(y 0)(c 0))

(定义(mod8 n)(模n 256))
(定义(mod32 n)(模n 4294967296))
(定义(参考i)(矢量参考t(mod8i))

(设置!mwc(λ()
(设置!z(mod32(+(*36969(logand z 65535))(灰度z-16)))
(设置!w(mod32(+(*18000(对数w 65535))(灰w-16)))
(mod32(+(灰烬z 16)w))

(设置!shr3(λ()
(set!jsr(mod32(logxor jsr(ash jsr 17)))
(set!jsr(mod32(logxor jsr(ash jsr-13)))
(set!jsr(mod32(logxor jsr(ash jsr 5)))

(set!cong(λ())
(设置!jcong(mod32(+(*69069 jcong)1234567)))

(设置!fib(lambda()
(集合!b(mod32(+a b)))

(set!kiss(lambda())接吻
(mod32(+(logxor(mwc)(cong))(shr3)))

(集合!lfib4(λ()
(集合!c(mod8(+c 1)))
(向量集!t c(mod32(+(ref c)(ref(+c 58)))
(参考(+c 119))(参考(+178)))

(设置!swb(λ()
(集合!c(mod8(+c 1)))
(let((bro(如果(<x y)10)))
(设置!x(模式32(参考(+c 34)))
(设置!y(mod32(+(参考(+c 19))兄弟))
(向量集!t c(mod32(-x y))
(矢量参考c))

(set!uni(lambda())
(*(亲吻)2.328306e-10))

(集合!vni(λ()
(*(-(亲吻)2147483648)4.6566133-10))

(set!可设置(lambda(i1 i2 i3 i4 i5 i6)
(set!z i1)(set!w i2)(set,jsr i3)(set;jcong i4)
(集合!a i5)(集合!b i6)
(do((i 0(+i 1)))((=i 256))
(矢量设置!ti(亲吻))))

如果Scheme系统提供32位无符号整数及其相应的位操作,则随机数生成器的速度会快得多,无论是本机还是通过某种外部函数接口。如果您的方案系统没有提供这些功能,您需要原木,对数变换器来自标准前奏曲; 你还需要首次公开募股,由调用。您将需要断言标准前奏曲对于我们的测试程序版本:

(定义(测试)
(让(k 0))
(可设置12345 65435 34221 12345 9983651 95746118)
(do((i 0(+i 1)))((=i 1e6)(断言k 1064612766))(设置!k(lfib4)))
(do((i 0(+i 1)))((=i 1e6)(断言k 627749721))(设置!k(swb))
(do((i 0(+i 1)))((=i 1e6)(断言k 1372460312))(设置!k(亲吻))
(do((i 0(+i 1)))((=i 1e6)(断言k 1529210297))(集合!k(cong))
(do((i 0(+i 1)))((=i 1e6)(断言k 2642725982))(设置!k(shr3))
(do((i 0(+i 1)))((=i 1e6)(断言k 904977562))(设置!k(mwc))
(do((i 0(+i 1)))((=i 1e6)(断言k 3519793928))(设置!k(fib)))

您可以在以下位置运行程序http://programmingpraxis.codepad.org/sf8Z4pJP.

页:1 2

4对“George Marsaglia的随机数生成器”的回应

  1. […]在过去的练习中检查了几个不同的随机数生成器,包括唐纳德·科努特(Donald Knuth)在《标准前奏曲》(Standard Prelude)中使用的滞后fibonacci生成器。我们[…]

  2. 注意,SHR3发电机有缺陷:它实际上没有2^32-1的周期,但有几个不同的周期,有些周期很短。可能输入错误:应改为:

    #定义SHR3(jsr^=(jsr<>17),jsr^=(jsr<<5))

    也就是说,13和17已经互换。该发电机的周期为2^32-1,符合预期。

    还要注意,对于MWC发电机,您必须避免某些“坏”种子。

    我已经用C和Python实现了一些Marsaglia的生成器。还应适当检查有效种子。请参见:

    https://bitbucket.org/cmcqueen1975/simplerandom/wiki/主页

  3. 很抱歉,之前的评论的#define行被博客格式弄乱了,我不知道如何修复。

  4. […]构建了几个随机数生成器:[1]、[2]、[3]、[4]、[5]、[6]、[7]、[8]、[9](直到我回去看了看,我才意识到有这么多)。[…]

留下评论