伪随机数生成算法-梅森旋转(Mersenne Twister/MT)
今天主要是来研究梅森旋转算法,它是用来产生伪随机数的,实际上产生伪随机数的方法有很多种,比如线性同余法,
平方取中法等等。但是这些方法产生的随机数质量往往不是很高,而今天介绍的梅森旋转算法可以产生高质量的伪随
机数,并且效率高效,弥补了传统伪随机数生成器的不足。梅森旋转算法的最长周期取自一个梅森素数,
由此命名为梅森旋转算法。常见的两种为基于32位的MT19937-32和基于64位的MT19937-64。
由于梅森旋转算法是利用线性反馈移位寄存器(LFSR)产生随机数的,所以我们先来认识线性反馈移位寄存器。
首先,移位寄存器包括两个部分
(1)级,每一级包含一个比特,比如11010110是一个8级的移位寄存器产生的
(2)反馈函数,线性反馈移位寄存器的反馈函数是线性的,非线性反馈移位寄存器的反馈函数是非线性的
一个级的移位寄存器产生的序列的最大周期为,当然这个最大周期跟反馈函数有很大关系,线性反馈函数实
际上就是这个级的移位寄存器选取“某些位”进行异或后得到的结果,这里的“某些位”的选取很重要,得到线性反馈
函数之后,把这个移位寄存器的每次向右移动一位,把最右端的作为输出,把“某些位”的异或结果作为输入放到最左
端的那位,这样所有的输出对应一个序列,这个序列叫做M序列,是最长线性移位寄存器序列的简称。
上面“某些位”的选取问题还没有解决,那么应该选取哪些位来进行异或才能保证最长周期为,这是一个很重要
的问题。选取的“某些位”构成的序列叫做抽头序列,理论表明,要使LFSR得到最长的周期,这个抽头序列构成的多项
式加1必须是一个本原多项式,也就是说这个多项式不可约,比如。
下面以一个4位的线性反馈移位寄存器为例说明它的工作原理。
如果的值分别是1 0 0 0,反馈函数选取,那么得到如下序列
可以看出周长为15。在这一个周期里面涵盖了开区间内的所有整数,并且都是没有固定顺序出现的,有
很好的随机性。
之前说过,梅森旋转算法的周期为,那么说明它是一个19937级的线性反馈移位寄存器,实际上基于32位
的MT19937-32只需要用到32位,那么为什么要选择周长为的算法呢? 那是因为这样做随机性很好。
梅森旋转算法是基于线性反馈移位寄存器的一直进行移位旋转,周期为一个梅森素数,果然是名副其实。
梅森旋转算法(Mersenne twister)是一个伪随机数发生算法。由松本真和西村拓士[1]在1997年开发,基于有限二进制字段上的矩阵线性递归。可以快速产生高质量的伪随机数, 修正了古典随机数发生算法的很多缺陷。
梅森旋转算法是R,Python,Ruby,IDL,Free Pascal,PHP,Maple,Matlab,GMP和GSL的默认伪随机数产生器。从C++11开始,C++也可以使用这种算法。在Boost C++,Glib和NAG数值库中,作为插件提供。 在SPSS中,梅森选旋转算法是两个PRNG中的一个:另一个是产生器仅仅为保证旧程序的兼容性,梅森旋转被描述为”更加可靠“。梅森旋转在SAS中同样是PRNG中的一个,另一个产生器是旧时的且已经被弃用。
最为广泛使用Mersenne Twister的一种变体是MT19937,可以产生32位整数序列。具有以下的优点:
有219937 − 1的非常长的周期。在许多软件包中的短周期—232 随机数产生器在一个长周期中不能保证生成随机数的质量。[2
在1 ≤ k ≤ 623的维度之间都可以均等分布(参见定义).
除了在统计学意义上的不正确的随机数生成器以外, 在所有伪随机数生成器法中是最快的(当时)
算法详细
本算法基于标准(线性)旋转反馈移位寄存器(twisted generalised feedback shift register/TGFSR)产生随机数
算法中用到的变量如下所示:
·w:长度(以bit为单位)
·n:递归长度
·m:周期参数,用作第三阶段的偏移量
·r:低位掩码/低位要提取的位数
·a:旋转矩阵的参数
·f:初始化梅森旋转链所需参数
·b,c:TGFSR的掩码
·s,t:TGFSR的位移量
·u,d,l:额外梅森旋转所需的掩码和位移量
MT19937-32的参数列表如下:
·(w, n, m, r) = (32, 624, 397, 31)
·a = 9908B0DF(16)
·f = 1812433253
·(u, d) = (11, FFFFFFFF16)
·(s, b) = (7, 9D2C568016)
·(t, c) = (15, EFC6000016)
·l = 18
MT19937-64的参数列表如下:
·(w, n, m, r) = (64, 312, 156, 31)
·a = B5026F5AA96619E9(16)
·f = 6364136223846793005
·(u, d) = (29, 555555555555555516)
·(s, b) = (17, 71D67FFFEDA6000016)
·(t, c) = (37, FFF7EEE00000000016)
·l = 43
参考链接:
https://github.com/xuwei-k/tinymt
https://en.wikipedia.org/wiki/Mersenne_Twister#TinyMT
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/JAVA/index.html
https://cs.gmu.edu/~sean/research/mersenne/MersenneTwister.java
https://cs.gmu.edu/~sean/research/mersenne/MersenneTwisterFast.java
http://commons.apache.org/proper/commons-rng/
伪随机数生成算法-梅森旋转(Mersenne Twister/MT)的更多相关文章
- Mersenne twister 随机数算法实现 in Scheme
这个实现基本上是从 Wiki 上的 Python 版翻译过来的,大量使用了赋值. ;; Mersenne twister algorithm from Wikipedia ;; returns a c ...
- PHP Math 函数 mt_rand() 使用 Mersenne Twister 算法返回随机整数。
语法 mt_rand(min,max) 说明 如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 RAND_MAX 之间的伪随机数.例如想要 5 到 15(包括 5 和 15) ...
- random——伪随机数生成模块
random——伪随机数生成模块 转自:https://blog.csdn.net/zhtysw/article/details/79978197 该模块包含构造伪随机数生成器的多个方法.对于整数,伪 ...
- C++ 凸包生成算法
由于我的极差记忆力,我打算把这个破玩意先记下来.因为以后会有改动(Delaunay三角网生成算法),我不想把一个好的东西改坏了... 好吧-- 凸包生成算法,: 1.先在指定的宽(width)高(he ...
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
- 分布式全局不重复ID生成算法
分布式全局不重复ID生成算法 算法全局id唯一id 在分布式系统中经常会使用到生成全局唯一不重复ID的情况.本篇博客介绍生成的一些方法. 常见的一些方式: 1.通过DB做全局自增操作 优点:简单.高 ...
- C++ 基于凸包的Delaunay三角网生成算法
Delaunay三角网,写了用半天,调试BUG用了2天……醉了. 基本思路比较简单,但效率并不是很快. 1. 先生成一个凸包: 2. 只考虑凸包上的点,将凸包环切,生成一个三角网,暂时不考虑Delau ...
- RocketMQ msgId生成算法
当我们用RocketMQ发送信息的时候通常都会返回如下信息: SendResult [sendStatus=SEND_OK, msgId=0A42333A0DC818B4AAC246C290FD000 ...
- 分布式系统的唯一id生成算法你了解吗?
在分库分表之后你必然要面对的一个问题,就是id咋生成? 因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那肯定不对啊. 举个例子,你的订单表拆分为了1024张订单表,每个表的id都从 ...
随机推荐
- mysql中查看数据库的版本,什么版本
需求:查看当前使用的数据库是哪个版本的,什么版本 select version(); 查询结果: 备注:通过version()函数查询出来当前使用的数据库版本是5.5.57-log 文档创建时间:20 ...
- c++浅拷贝和深拷贝---14
原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 1.什么是拷贝构造函数: 拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来 ...
- [Scikit-learn] 2.5 Dimensionality reduction - ICA
理论学习: 独立成分分析ICA历史 Ref: Lecture 15 | Machine Learning (Stanford) - NG From: https://wenku.baidu.com/v ...
- AndroidManifest详解
一,重要性AndroidManifest.xml是Android应用程序中最重要的文件之一.它是Android程序的全局配置文件,是每个 android程序中必须的文件.它位于我们开发的应用程序的根目 ...
- SpringBoot------注解把配置文件自动映射到属性和实体类
1.映射到属性 package top.ytheng.demo.controller; import org.springframework.beans.factory.annotation.Valu ...
- VSCode------搭建.net core 2.0,并配置到IIS服务器
前奏 安装VSCode最新版: https://code.visualstudio.com/ 安装window server hosting,发布和部署到IIS使用: https://www.micr ...
- Java实现快速批量移动文件
文件移动是计算机资源管理常用的一个操作,这在操作系统中可以通过文件的剪切与复制或鼠标拖动来实现.但是在Java文件的编程实现中,大多是通过复制文件到目的地,再删除所有文件来实现的.这对于小文件来说看不 ...
- WPF导航总结
使用导航的目的是从一个页面进入到另一个页面.无论是预先决定的线性顺序(向导)还是基于层次的用户驱动程序(大部分网站的形式),或者动态生成的路径,主要有3种方法实现:调用Navigate方法,使用Hyp ...
- python爬虫系列:做一个简单的动态代理池
自动 1.设置动态的user agent import urllib.request as ure import urllib.parse as upa import random from bs4 ...
- vi 中大小写转换功能
所有的操作都是围绕着“gu"和“gU”另个命令展开的.secooler的语法:[开始位置]gu/Gu[结束位置]secooler的翻译: [开始位置] ---- 可以指定开始的位置,默认是光 ...