今天主要是來研究梅森旋轉算法,它是用來產生僞隨機數的,實際上產生僞隨機數的方法有很是多種,比方線性同餘法,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位的隨機數就是這個
網址的信息指紋,可以證實,僅僅要產生的隨機數足夠好,那麼就可以保證差點兒不可能有兩個網址的信息指紋一樣,就
如同不可能有兩我的的指紋一樣同樣,而梅森旋轉算法是產生高質量僞隨機數的算法。