線性反饋移位寄存器與梅森旋轉算法

今天主要是來研究梅森旋轉算法,它是用來產生僞隨機數的,實際上產生僞隨機數的方法有很是多種,比方線性同餘法,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位的隨機數就是這個

網址的信息指紋,可以證實,僅僅要產生的隨機數足夠好,那麼就可以保證差點兒不可能有兩個網址的信息指紋一樣,就

如同不可能有兩我的的指紋一樣同樣,而梅森旋轉算法是產生高質量僞隨機數的算法。

相關文章
相關標籤/搜索