今天主要是来研究梅森旋转算法,它是用来产生伪随机数的,实际上产生伪随机数的方法有很是多种,比方线性同余法,ios
平方取中法等等。但是这些方法产生的随机数质量每每不是很是高,而今天介绍的梅森旋转算法可以产生高质量的伪随算法
机数,并且效率高效,弥补了传统伪随机数生成器的不足。梅森旋转算法的最长周期取自一个梅森素数,由dom
此命名为梅森旋转算法。常见的两种为基于32位的MT19937-32和基于64位的MT19937-64。函数
由于梅森旋转算法是利用线性反馈移位寄存器(LFSR)产生随机数的,因此咱们先来认识线性反馈移位寄存器。搜索引擎
首先,移位寄存器包含两个部分spa
(1)级,每一级包括一个比特,比方11010110是一个8级的移位寄存器产生的code
(2)反馈函数,线性反馈移位寄存器的反馈函数是线性的,非线性反馈移位寄存器的反馈函数是非线性的blog
一个级的移位寄存器产生的序列的最大周期为
,固然这个最大周期跟反馈函数有很是大关系,线性反馈函数实索引
际上就是这个级的移位寄存器选取“某些位”进行异或后获得的结果,这里的“某些位”的选取很是重要,获得线性反ip
馈函数以后,把这个移位寄存器的每次向右移动一位,把最右端的做为输出,把“某些位”的异或结果做为输入放到最
左端的那位,这样所有的输出相应一个序列,这个序列叫作M序列,是最长线性移位寄存器序列的简称。
上面“某些位”的选取问题尚未解决,那么应该选取哪些位来进行异或才干保证最长周期为,这是一个很是重要
的问题。选取的“某些位”构成的序列叫作抽头序列,理论代表,要使LFSR获得最长的周期,这个抽头序列构成的多
项式加1必须是一个本原多项式,也就是说这个多项式不可约,比方。
如下以一个4位的线性反馈移位寄存器为例说明它的工做原理。
假设的值各自是1 0 0 0,反馈函数选取
,那么获得例如如下序列
可以看出周长为15。在这一个周期里面涵盖了开区间内的所有整数,并且都是没有固定顺序出现的,有很是好
的随机性。
以前说过,梅森旋转算法的周期为,那么说明它是一个19937级的线性反馈移位寄存器,实际上基于32位
的MT19937-32仅仅需要用到32位,那么为何要选择周长为的算法呢? 那是因为这样作随机性很是好。
梅森旋转算法是基于线性反馈移位寄存器的一直进行移位旋转,周期为一个梅森素数,果真是名副其实。
代码:
#include <iostream> #include <string.h> #include <stdio.h> #include <time.h> using namespace std; bool isInit; int index; int MT[624]; //624 * 32 - 31 = 19937 void srand(int seed) { index = 0; isInit = 1; MT[0] = seed; for(int i=1; i<624; i++) { int t = 1812433253 * (MT[i-1] ^ (MT[i-1] >> 30)) + i; MT[i] = t & 0xffffffff; //取最后的32位 } } void generate() { for(int i=0; i<624; i++) { // 2^31 = 0x80000000 // 2^31-1 = 0x7fffffff int y = (MT[i] & 0x80000000) + (MT[(i+1) % 624] & 0x7fffffff); MT[i] = MT[(i + 397) % 624] ^ (y >> 1); if (y & 1) MT[i] ^= 2567483615; } } int rand() { if(!isInit) srand((int)time(NULL)); if(index == 0) generate(); int y = MT[index]; y = y ^ (y >> 11); y = y ^ ((y << 7) & 2636928640); y = y ^ ((y << 15) & 4022730752); y = y ^ (y >> 18); index = (index + 1) % 624; return y; } int main() { srand(0); //设置随机种子 int cnt = 0; for(int i=0; i<1000000; i++) { if(rand() & 1) cnt++; } cout<<cnt / 10000.0<<"%"<<endl; return 0; }
实际上在很是多语言中的随机数函数都已经採用了梅森旋转法实现,比方Python中的随机数模块random就是採用了梅
森旋转算法来产生伪随机数列,C++11中也有梅森旋转算法实现的随机数生成器。
梅森旋转算法在信息指纹技术中的应用
在百度或者Google这种搜索引擎中,爬虫要对爬取的网页进行判重,这个是经过信息指纹来实现的。详细来讲就
是把每一个网址随机地映射到128位二进制,这样每一个网址仅仅占用16个字节的空间,这个128位的随机数就是这个
网址的信息指纹,可以证实,仅仅要产生的随机数足够好,那么就可以保证差点儿不可能有两个网址的信息指纹一样,就
如同不可能有两我的的指纹一样同样,而梅森旋转算法是产生高质量伪随机数的算法。