首页 > 编程知识 正文

线性时间选择算法图解(线性反馈移位寄存器与梅森旋转算法)

时间:2023-05-04 09:24:09 阅读:121469 作者:1157

今天主要是来研究俏皮的镜子旋转算法。 它用于生成伪随机数。 实际上生成伪随机数的方法有很多种。 例如,线性综合法

平方取中法等。 然而,这些方法生成的随机数质量往往不高,而今天介绍的俏皮的镜子旋转算法可以生成高质量的伪随

机数高效,弥补了传统伪随机数发生器的不足。俏皮的镜子旋转算法的最长周期取自俏皮的镜素数,

由此命名为俏皮的镜子旋转算法。 常见的两种类型是基于32位的MT19937-32和基于64位的MT19937-64

俏皮的镜子旋转算法利用线性反馈移位寄存器(LFSR)生成随机数,让我们先识别3358www.Sina.com/。

首先,移位寄存器由两部分组成

)所述级包含每个级的比特,例如由线性反馈移位寄存器11010110级的移位寄存器生成

)反馈函数、线性反馈移位寄存器的反馈函数是线性的,非线性反馈移位寄存器的反馈函数是非线性的

1级移位寄存器生成序列的最大周期,当然该最大周期与反馈函数有很大关系,线性反馈函数是实的

此时,这是该级移位寄存器选择“某个位”进行异或的结果,这里的“某个位”的选择很重要,可以得到线性反馈

函数后,将该移位寄存器的每1位向右移动,将右端的作为输出,将“某位”的异或结果作为输入放在最左边

我是他。 这样,所有的输出都对应一个数组。 此数组称为8,是M序列的简称。

如果上述“某些位”选择问题尚未解决,那么应该选择哪个位以确保异或的最长周期是很重要的

请参阅。 将由所选择的“某个比特”构成的序列称为抽头序列。理论上,该抽头序列构成多个项,以便最长线性移位寄存器序列获得最长的周期

表达式加LFSR必须为1。 也就是说,这个多项式不能约定如下。

以下,以4位线性反馈移位寄存器为例说明动作原理。

如果的值分别为本原多项式,并且选择了反馈函数,则会生成以下序列

可知周长为1 0 0 0。 此周期包含开放区间内的所有整数,不会以一定的顺序出现

很随机。

如上所述,俏皮的镜子旋转算法的周期是15级线性反馈移位寄存器,实际上基于19937

32只使用MT19937-32位,为什么要选择周长为的算法呢? 那是因为随机性很好。

俏镜旋转算法基于线性反馈移位寄存器始终进行移位旋转,周期为俏镜素数,仍然名副其实。

32

# include iostream # include string.h # include stdio.h # include time.husingnamespacestd; bool isInit; 索引; int MT[624]; //624 * 32-31=19937语音扫描(int seed ) { index=0; isInit=1; mt[0]=引脚; //初始化数组其他元素的for(intI=1; i 624; I ) intt=1812433253 * (mt [ I-1 ] ^ (mt [ I-1 ] 30 ) ) I; MT[i]=t0xffffffff; //取最后32位MT[i] }} void generate () for ) intI=0; i 624; I ()/2 ) 31=0x80000000//2) 31-1=0x7fffffff inty=(mt [ I ]0x 8000000 ) (mt ) ) (I1 ) ) )。

) % 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右移11个bit y = y ^ ((y << 7) & 2636928640); //y左移7个bit与2636928640相与,再与y进行异或 y = y ^ ((y << 15) & 4022730752); //y左移15个bit与4022730752相与,再与y进行异或 y = y ^ (y >> 18); //y右移18个bit再与y进行异或 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中也有俏皮的镜子旋转算法实现的随机数生成器。用法可以参考下面链接

 

链接:http://www.tuicool.com/articles/BfaYvm

 

链接:http://www.cnblogs.com/egmkang/archive/2012/09/06/2673253.html

 

链接:http://www.cplusplus.com/reference/random/

 

 

俏皮的镜子旋转算法在信息指纹技术中的应用

 

百度或者Google这样的搜索引擎中,爬虫要对爬取的网页进行判重,这个是通过信息指纹来实现的。具体来说就

是把每一个网址随机地映射到128位二进制,这样每一个网址只占用16个字节的空间,这个128位的随机数就是这个

网址的信息指纹,可以证明,只要产生的随机数足够好,那么就可以保证几乎不可能有两个网址的信息指纹相同,就

如同不可能有两个人的指纹相同一样,而俏皮的镜子旋转算法是产生高质量伪随机数的算法。

 

有关俏皮的镜子旋转算法的详细资料,参考Wiki:http://en.wikipedia.org/wiki/Mersenne_twister

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。