这个实现基本上是从 Wiki 上的 Python 版翻译过来的,大量使用了赋值。

;; Mersenne twister algorithm from Wikipedia
;; returns a closure that returns a pseudo-random integer
;; for each call
;;
(define (make-MT19937 seed)
;; some bitwise procedure alias for short
(define << bitwise-arithmetic-shift-left)
(define >> bitwise-arithmetic-shift-right)
(define xor bitwise-xor) (letrec ((mt (make-vector 624))
(index 624)
;; reset index
(twist
(lambda ()
(for i in (range 624)
(let ((y (bitwise-and
#xffffffff
(+ (bitwise-and (vector-ref mt i)
#x80000000)
(bitwise-and (vector-ref mt (mod (+ i 1) 624))
#x7fffffff)))))
(vector-set! mt i (xor (vector-ref mt (mod (+ i 397) 624))
(>> y 1)))
(when (odd? y)
(vector-set!
mt i (xor (vector-ref mt i) #x9908b0df)))))
(set! index 0)))
;; generates a number
(extract_number
(lambda ()
(when (>= index 624)
(twist))
(let ((y (vector-ref mt index))) (set! y (xor y (>> y 11)))
(set! y (xor y (bitwise-and (<< y 7) 2636928640)))
(set! y (xor y (bitwise-and (<< y 15) 4022730752)))
(set! y (xor y (>> y 18)))
(set! index (+ index 1))
(bitwise-and #xffffffff y))))) (vector-set! mt 0 seed) ;; initialize the vector
(for i in (range 1 624)
(vector-set!
mt
i
(bitwise-and (+ i
(* 1812433253
(bitwise-xor (vector-ref mt (- i 1))
(>> (vector-ref mt (- i 1)) 30))))
#xffffffff)))
;; return a closure
(lambda ()
(extract_number)))) ;; It may be better to set the seed as the system clock
;; but that involves different implementations
(define generator (make-MT19937 4294967296)) ;; the seed (define (randint . arg)
(if (null? arg)
(generator)
(mod (generator) (car arg))))

我使用了自己定义的 for 宏,以及 range 函数来实现 Python 风格的 for 循环,下面是相关的定义:

(define-syntax for
(syntax-rules ()
;; loop in list
;; (for i in '(a b c) do something...)
((_ i in lst body ...)
(let loop ((l lst))
(unless (null? l)
(let ((i (car l)))
body ...
(loop (cdr l)))))))) (define range
(let ((make-range
(lambda (first end step)
(if (or (= step 0)
(> (abs (- (+ first step) end))
(abs (- first end))))
(error 'range "wrong `step' leads to an infinite loop")
(let iter ((cnt first) (result '()))
(cond ((or (and (> step 0) (>= cnt end))
(and (< step 0) (<= cnt end)))
(reverse result))
(else (iter (+ cnt step) (cons cnt result)))))))))
(case-lambda
((a) (make-range 0 a 1))
((a b) (make-range a b 1))
((a b c) (make-range a b c)))))

使用了 R6RS 特有的一些函数及语法,使用时不要忘记在头部加上 (import (rnrs),如果还依赖别的库请查阅 R6RS 文档。

Mersenne twister 随机数算法实现 in Scheme的更多相关文章

  1. 伪随机数生成算法-梅森旋转(Mersenne Twister/MT)

    今天主要是来研究梅森旋转算法,它是用来产生伪随机数的,实际上产生伪随机数的方法有很多种,比如线性同余法, 平方取中法等等.但是这些方法产生的随机数质量往往不是很高,而今天介绍的梅森旋转算法可以产生高质 ...

  2. PHP Math 函数 mt_rand() 使用 Mersenne Twister 算法返回随机整数。

    语法 mt_rand(min,max) 说明 如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 RAND_MAX 之间的伪随机数.例如想要 5 到 15(包括 5 和 15) ...

  3. C语言生成32位和64位随机数算法

    C语言生成32位和64位随机数算法 /** * randstd.h * * Standard definitions and types, Bob Jenkins * * 2015-01-19: re ...

  4. 基于“均态分布”随机数算法的一次性口令OneTimePassword(原创)

    /* 所谓均态分布随机数算法是指:每个数(整数或实数)无序地分布在数轴上,值只出现一次永不重复.体现了香农的一次一密理论. * 均体现在每个数的值是平均概率,即都有出现:态体现在每个数在数轴上的位置是 ...

  5. java基础 - 冒泡排序,随机数算法

    从简单做起 任何困难的事情都是由简单的一步步一件件事情堆起来 理解好算法才是最重要 1.冒泡排序: public class Test { public static void main(String ...

  6. **PHP随机数算法

    <?php $tmp = range(1,30);print_r(array_rand($tmp,10));?> 输出: Array( [0] => 6 [1] => 8 [2 ...

  7. js随机数算法

    function rnd( seed ){ seed = ( seed * 9301 + 49297 ) % 233280; //为何使用这三个数? return seed / ( 233280.0 ...

  8. C/C++ 开源库及示例代码

    C/C++ 开源库及示例代码 Table of Contents 说明 1 综合性的库 2 数据结构 & 算法 2.1 容器 2.1.1 标准容器 2.1.2 Lockfree 的容器 2.1 ...

  9. PHP Math 函数

    abs() 绝对值. 3 acos() 反余弦. 3 acosh() 反双曲余弦. 4 asin() 反正弦. 3 asinh() 反双曲正弦. 4 atan() 反正切. 3 atan2() 两个参 ...

随机推荐

  1. ABP 初探 之 AbpSession 扩展

    Abp的权限管理是基于 Identity,所有的扩展也是基于 claims .claims 有许多默认属性,具体连接 关于 Identity的详细介绍,可以参考园友博客 继承 Microsoft.As ...

  2. Maven命令行使用:mvn clean package(打包)

    先把命令行切换到Maven项目的根目录,比如:/d/xxxwork/java/maven-test,然后执行命令:  mvn clean package 执行结果如下: [INFO] Scanning ...

  3. 十一个行为模式之访问者模式(Visitor Pattern)

    定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...

  4. .NET程序员走向高端必读书单汇总

    .NET程序员走向高端必读书单汇总 一.知识树 1. 基本能力 1.1 数学 1.2 英语 1.3 语言表达 2. 计算机组织与体系结构 3. 算法与数据结构 4. 操作系统 5. 计算机网络 6. ...

  5. golang官网可以打开了 go语言

    golang.org之前国内一直打不开,今天看了一下居然可以打开了,除了页面上youtube的视频加载不了.页面自动识别中文. 再也不用为下载go的源码发愁了.http://www.cnblogs.c ...

  6. SharePoint 2013 入门教程之创建及修改母版页

    在SharePoint 2013中,微软提供了根据HTML页面转换Master页的方法,并支持单项同步,但是这样的更新,并不完善,会使一些功能造成丢失,所以,了解Master结构的人,尽量直接去修改M ...

  7. asp.netDataTable导出excel方法(2)

    上一篇文章提到看到同事导出excel的新方法,感觉比上一篇简单得多,所以想贴上来,与大家分享. 在后台拼数据,都是用的htmltable标签的写法: string line = "text- ...

  8. html5快速入门(四)—— JavaScript

    前言: 1.HTML5的发展非常迅速,可以说已经是前端开发人员的标配,在电商类型的APP中更是运用广泛,这个系列的文章是本人自己整理,尽量将开发中不常用到的剔除,将经常使用的拿出来,使需要的朋友能够真 ...

  9. React Native知识5-Touchable类组件

    React Native 没有像web那样可以给元素绑定click事件,前面我们已经知道Text组件有onPress事件,为了给其他组件 也绑定点击事件,React Native提供了3个组件来做这件 ...

  10. 【iOS】屏幕适配之NSLayoutConstraint

    前言 如何实现一张图片在iPhone和iPad上显示不同的尺寸,我了解到一般有三种办法:直接手写代码动态添加约束:把NSLayoutConstraint关联到ViewController里再viewD ...