这个实现基本上是从 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. ASP.NET MVC搭建项目后台UI框架—7、统计报表

    ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NET M ...

  2. entityframework学习笔记--001

    最近想重新好好学习一下entityframework,于是在院子里找到了一篇不错的博客.下面把学习的过程记录下来,方便以后复习. 学习过程参考大神的博客:http://www.cnblogs.com/ ...

  3. zookeeper集群

    0,Zookeeper基本原理 ZooKeeper集群由一组Server节点组成,这一组Server节点中存在一个角色为Leader的节点,其他节点都为Follower.当客户端Client连接到Zo ...

  4. OData V4 系列 查询操作

    OData 学习目录 对OData的操作,主要是查询,下面把相关的查询情况列出来,供参考学习,每个操作都有对应的截图,便于理解 默认查询 $expand  查询导航属性关系 ,查询Product相关的 ...

  5. 探讨webapp的SEO难题(上)

    前言 网络蜘蛛无法解析javascript,至少百度是不能的,神马搜索差的更远,而我们的webapp的渲染展示完全由javascript驱动 所以蜘蛛访问webapp页面会得到一个白页面,比如,我们期 ...

  6. 字体属性设置(一):谷歌浏览器12px以下字体的显示;方法和原理

    前言: chrome 谷歌浏览器默认的字体大小为16px:可以通过设置font-size来设置字体大小但是当设置到12px以下的时候字体大小不再改变:对于想设置其他大小的字体就很头疼,本文参考网上的方 ...

  7. SharePoint 2013 图文开发系列之WebPart

    这是我们介绍SharePoint开发入门的第一篇,在这一篇里,我们会介绍SharePoint开发的几个关键物理路径,一些开发技巧和最基础的WebPart开发. 开发工具 在SharePoint 201 ...

  8. tabbarItem字体及图片颜色设置

    tabbarItem设置图片后运行往往与我们原始图片颜色有出入,这是因为在默认情况下,未选中状态图片和字体颜色为灰色,选中状态下图片和字体颜色为蓝色.   UIImage 在呈现(render)时会选 ...

  9. React Native环境配置和简单使用

    # 前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会 ...

  10. 从0到1,教你实现基于Ruby的watir-webdriver自动化测试

    一.为什么选择Ruby []完全开源. []多平台:Ruby可以运行在Linux, UNIX, Windows, MS-DOS, BeOS, OS/.. []多线程:线程就是指在一个程序中处理若干控制 ...