免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
【洛谷日報(bào)#224】關(guān)于隨機(jī)數(shù)的前世今生

提起隨機(jī)數(shù),大家一定都不陌生。無論是在計(jì)算機(jī)科學(xué)領(lǐng)域,還是現(xiàn)實(shí)生活中,隨機(jī)數(shù)的作用都不可小覷。

但隨機(jī)數(shù)究竟是怎么一會事?它的作用是什么?它有事如何產(chǎn)生的?

本文會著重談計(jì)算機(jī)的隨機(jī)數(shù)以及產(chǎn)生算法,偏理論的只是會放到另一篇博客上隨機(jī)數(shù)那些事

隨機(jī)數(shù)定義及其性質(zhì)

想要討論隨機(jī)數(shù),首先應(yīng)該明確一下隨機(jī)數(shù)的定義。畢竟這個東西比較虛,并不像算法那樣明確。在各大網(wǎng)上也沒有給出很好的定義。

那…就不死摳定義了。

隨機(jī)數(shù)一般來說符合下面這幾個性質(zhì)。

  1. 它產(chǎn)生時后面那個數(shù)與前面的毫無關(guān)系

  2. 給定樣本的一部分和隨機(jī)算法,無法推出樣本的剩余部分

  3. 其隨機(jī)樣本不可重現(xiàn)

另外還要說一下統(tǒng)計(jì)學(xué)偽隨機(jī)數(shù)概念,劃重點(diǎn)

統(tǒng)計(jì)學(xué)偽隨機(jī)性。統(tǒng)計(jì)學(xué)偽隨機(jī)性指的是在給定的隨機(jī)比特流樣本中,1的數(shù)量大致等于0的數(shù)量,同理,“10”“01”“00”“11”四者數(shù)量大致相等。類似的標(biāo)準(zhǔn)被稱為統(tǒng)計(jì)學(xué)隨機(jī)性。滿足這類要求的數(shù)字在人類“一眼看上去”是隨機(jī)的。(摘自百度詞條)

實(shí)際上這也是在計(jì)算機(jī)中對偽隨機(jī)數(shù)優(yōu)劣的概念。

continue->

偽隨機(jī)數(shù)

偽隨機(jī)數(shù),也就是我們c++中常用的隨機(jī)數(shù)。為什么說它是“偽”隨機(jī)呢?其實(shí)只要稍微詳細(xì)的了解過c++ rand函數(shù)的人應(yīng)該都能懂得這一點(diǎn)。

因?yàn)橛?jì)算機(jī)本身并不能夠產(chǎn)生和隨機(jī)數(shù),只能通過產(chǎn)生一組循環(huán)節(jié)很長的數(shù)來“偽造”隨機(jī)。

c++的rand函數(shù)實(shí)際上只是根據(jù)你提供的種子計(jì)算出來的一組循環(huán)節(jié)很長的數(shù)。只要兩次提供的種子是一樣的,那么rand函數(shù)提供的隨機(jī)數(shù)也是一樣的。

可能有好奇的小伙伴就要問了,你說循環(huán)節(jié)很長,那到底長到什么程度呢?

經(jīng)過不懈的努力,筆者成功弄到了rand()函數(shù)在LINUX系統(tǒng)下的實(shí)現(xiàn):

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
    next = seed;
}

( 該代碼摘自CSDN 原文鏈接

通過這個算法我們可以推知,rand函數(shù)的循環(huán)節(jié)應(yīng)該是在32768(2的15次方)以內(nèi)。

( 所以我白測試了是嗎 )

做這些測試實(shí)際上就是想說,在計(jì)算機(jī)方面。目前來說,如果不借助外部幫助,是無法達(dá)到真隨機(jī)的。

計(jì)算機(jī)的隨機(jī)數(shù)

計(jì)算機(jī)隨機(jī)數(shù)的產(chǎn)生,我在講偽隨機(jī)時已經(jīng)水過做過介紹了,也就不多說。

你以為我會幫忙把前面的代碼拷過來嗎?想太多了,自己翻頁去。

( 本來想放點(diǎn)圖可能可以增加可讀性,但好像放不了什么… )

這里我主要想講的是關(guān)于計(jì)算機(jī)在沒有外界幫助下為什么不能產(chǎn)生真隨機(jī)數(shù)。

真隨機(jī)數(shù)的產(chǎn)生應(yīng)該是與之前的數(shù)是沒有任何關(guān)聯(lián)的( 論證過 ),那么在計(jì)算機(jī)中想對應(yīng)的就是產(chǎn)生隨機(jī)數(shù)的函數(shù)應(yīng)該不需要調(diào)用任何參數(shù)( 因?yàn)橐坏┱{(diào)用了的參數(shù),那么這個隨機(jī)數(shù)的產(chǎn)生就會與參數(shù)相關(guān) )那么對于計(jì)算機(jī)來說,如何不調(diào)用任何參數(shù)并且產(chǎn)生不同的數(shù)呢?

這個…好像做不到。

這個換一個思維來解釋好一點(diǎn)。因?yàn)橛?jì)算機(jī)是一個絕對理智的存在,也就是說,計(jì)算機(jī)的一切行為都是可預(yù)測可推導(dǎo)的。而這恰恰違背了我們隨機(jī)數(shù)標(biāo)準(zhǔn)中的第二條,即不可推斷。對于計(jì)算機(jī)的任何程序,如果使用完全相同的參數(shù)來調(diào)用,它所輸出的結(jié)果一定是完全一樣的

農(nóng)夫山泉不生產(chǎn)水,他們只是大自然的搬運(yùn)工

計(jì)算機(jī)不生產(chǎn)數(shù)據(jù),它只是數(shù)據(jù)的加工廠。

真隨機(jī)數(shù)生成

不是重點(diǎn),知道了就好。

真隨機(jī)數(shù)生成器是一種通過物理過程而不是計(jì)算機(jī)程序來生成隨機(jī)數(shù)字的設(shè)備。

這樣的設(shè)備通常是基于一些能生成低等級、統(tǒng)計(jì)學(xué)隨機(jī)的“噪聲”信號的微觀現(xiàn)象,如熱力學(xué)噪聲、光電效應(yīng)和量子現(xiàn)象。這些物理過程在理論上是完全不可預(yù)測的,并且已經(jīng)得到了實(shí)驗(yàn)的證實(shí)。硬件隨機(jī)數(shù)生成器通常由換能器、放大器和模擬數(shù)字轉(zhuǎn)換器組成。其中換能器用來將物理過程中的某些效果轉(zhuǎn)換為電信號,放大器及其電路用來將隨機(jī)擾動的振幅放大到宏觀級別,而模擬數(shù)字轉(zhuǎn)換器則用來將輸出變成數(shù)字,通常是二進(jìn)制的零和一。通過重復(fù)采樣這些隨機(jī)的信號,一系列的隨機(jī)數(shù)得以生成。

(摘自百度詞條原文鏈接

隨機(jī)數(shù)在OI中的常見應(yīng)用

首先是用于檢驗(yàn)程序。

估計(jì)這是大部分OIer的用法,拿一個隨機(jī)數(shù)生成器去驗(yàn)證程序的速度,以及是否會RE( 正確率是測不了的,畢竟自己手推答案比較慢 )。

然后的話是某些算法的需要

這里因?yàn)樗惴ㄌ?,筆者也就大概介紹一下:

  1. 大家熟悉的平衡樹treap,它是通過生成隨機(jī)權(quán)值引導(dǎo)進(jìn)行旋轉(zhuǎn)操作來使樹接近平衡。

  2. 相對常見的模擬退火就是隨機(jī)算法的一個極致實(shí)現(xiàn)。它通過完全隨機(jī)的操作變換解,使其不斷接近正解。也是大家在OI中最多的用法。

  3. 可能大家相對陌生的遺傳算法中也有隨機(jī)數(shù)的體現(xiàn)。主要表現(xiàn)在交叉和變異兩方面上。

  4. 可能大家聽都沒通說過的Pollard_Rho算法,就是超大數(shù)的分解質(zhì)因數(shù)。因?yàn)閿?shù)字過大無法用O(N)的算法。此時我們就通過隨機(jī)數(shù)去“猜”質(zhì)因數(shù):不斷生成隨機(jī)值,判斷是否出現(xiàn)兩者之差為因子。(因?yàn)閮烧卟顬橹付ㄖ档某霈F(xiàn)概率會比一個個猜大一倍),然后不斷遞歸隨機(jī)到的那個因子和那個數(shù)初一因子的另一半,直到找到質(zhì)因子。具體算法比較復(fù)雜。有機(jī)會單獨(dú)寫一篇講。模板題傳送門

  5. 然后與遺傳算法類似的粒子群算法,隨機(jī)主要出現(xiàn)在單個粒子的更新上。

  6. 蟻群算法有用到,但因?yàn)檫^于冷門,就不多做介紹了。

( 感覺隨機(jī)數(shù)好像也就這么點(diǎn)用,在密碼學(xué)統(tǒng)計(jì)學(xué)中用的比較多 )

隨機(jī)數(shù)優(yōu)劣判定

在講隨機(jī)數(shù)算法之前,應(yīng)該先講講隨機(jī)數(shù)優(yōu)劣的判定。

畢竟只有清除了隨機(jī)數(shù)的優(yōu)劣,我們才能說如何生成優(yōu)質(zhì)隨機(jī)數(shù)。

在這里我們就要用到前面說的統(tǒng)計(jì)學(xué)偽隨機(jī)性:

統(tǒng)計(jì)學(xué)偽隨機(jī)性。統(tǒng)計(jì)學(xué)偽隨機(jī)性指的是在給定的隨機(jī)比特流樣本中,1的數(shù)量大致等于0的數(shù)量,同理,“10”“01”“00”“11”四者數(shù)量大致相等。類似的標(biāo)準(zhǔn)被稱為統(tǒng)計(jì)學(xué)隨機(jī)性。滿足這類要求的數(shù)字在人類“一眼看上去”是隨機(jī)的。(我?guī)兔Π嵯聛砹耍?/p>

結(jié)合計(jì)算機(jī)隨機(jī)數(shù)的特性,我們能夠得出以下三項(xiàng)判斷隨機(jī)數(shù)優(yōu)劣的性質(zhì):

  1. 隨機(jī)程度,即隨機(jī)算法是否足夠復(fù)雜,隨機(jī)數(shù)之間會不會存在明顯聯(lián)系。

  2. 分布范圍,即是否存在隨機(jī)數(shù)在分布區(qū)域內(nèi)大量出現(xiàn)偏大偏小的現(xiàn)象。分布是否足夠平均。

  3. 循環(huán)長度,即是否會在大量調(diào)用時很快地出現(xiàn)循環(huán)的情況。

有了這些評判規(guī)則,我們就比較好學(xué)習(xí)優(yōu)質(zhì)隨機(jī)數(shù)的生成。

如何生成優(yōu)質(zhì)隨機(jī)數(shù)

終于到了塞實(shí)貨時間。

水不動了

這里前三個我講一下在rand函數(shù)調(diào)用基礎(chǔ)上自己做一點(diǎn)小操作來產(chǎn)生三種不同特性的隨機(jī)數(shù)。

第四個專題講MT19337算法(重點(diǎn),絕對的重點(diǎn)),也就是目前優(yōu)質(zhì)隨機(jī)數(shù)生成的普遍算法。

來回?cái)[動式

這種隨機(jī)數(shù)主要是針對退火算法之類的需要用隨機(jī)數(shù)來修正答案的。

既然是修正答案,那么我們希望最好是來回?cái)[動,一正一負(fù)的。

這種隨機(jī)數(shù)的特點(diǎn)便是通過一部分人工處理,將原本的rand函數(shù)產(chǎn)生的隨機(jī)數(shù)變成正負(fù)交替的。

int f  = 3000 ;
int change = 0.999 ; // f和change是用來控制隨機(jī)數(shù)幅度不斷變小的 
int con = -1 ;
int g = 1 ; // 控制正負(fù)交替 
int newrand ( ) {
    f *= change ;
    g *= con ;
    int tmp =  f * g * rand ( ) ;
    return tmp ;
}

這種隨機(jī)數(shù)的產(chǎn)生引入了退火的思路,當(dāng)然,你也可以直接使用算法中現(xiàn)成的溫度來控制。

平均式

這種主要是用于平衡樹treap的,特點(diǎn)就是在保證單個數(shù)隨機(jī)的情況下在整體上保證分布比較平均。

實(shí)現(xiàn)原理也沒什么好講的,上代碼就完事了。

int p ; // 希望的分布位置 
int newrand ( ) {
    int tmp =  ( p + rand ( ) ) / 2 ; // 通過取于分布位置的平均數(shù),是產(chǎn)生的數(shù)更加靠近希望分布 
    return tmp ;
}

多次調(diào)用不重復(fù)式

當(dāng)然,如果有人真的需要非常接近真隨機(jī)的數(shù)。也就是多次運(yùn)行程序也不會出現(xiàn)相同的情況。那就需要用到一定的外部干擾了。

首先是clock函數(shù),上文已經(jīng)說過,一個程序在不斷調(diào)用期間。每一次的運(yùn)行時間都會有細(xì)小的變化。我們就可以利用好這個變化。每次調(diào)用完后都重置一次隨機(jī)數(shù)種子。

還有一個可能大家都會忽視的方法。計(jì)算機(jī)本身的誤差。眾所周知,計(jì)算機(jī)在做浮點(diǎn)運(yùn)算時是會產(chǎn)生精度損失的,那么我們也可以利用這個特點(diǎn)輔助clock調(diào)整種子(畢竟程序調(diào)用時間相同其實(shí)可能性也不小,畢竟clock只精確到s/1000)。

int count ;
int realrand ( ) {
    count ++ ;
    int t = clock ( ) + 1 ; // 使用當(dāng)前時間 
    for ( int i = 1 ; i < 12121307 ; i ++ ) { // 降速(如果放到具體代碼里面使用可以將此參數(shù)調(diào)低) 
        t += rand ( ) ;
    }
    t += clock ( ) ; // 降速后擴(kuò)大時間變化 
    t *= -1234 ;
    srand ( t * count + rand ( ) ) ; // 重置隨機(jī)數(shù)種子 
    return rand ( ) ;
}

筆者經(jīng)過大量實(shí)驗(yàn),發(fā)現(xiàn)該函數(shù)前三個數(shù)出現(xiàn)重復(fù)幾率相對會比較大(7~9%)建議從第四個開始使用。

上面的代碼我并沒用用精度損失來隨機(jī)化,因?yàn)槲野l(fā)現(xiàn)同一個式子的進(jìn)度損失值太小,以至于幾乎不會發(fā)生什么改變,所以并沒有使用。

隨機(jī)數(shù)優(yōu)劣度分析:

因?yàn)槿齻€函數(shù)實(shí)際上都是在調(diào)用rand()函數(shù),所以實(shí)際上他們的優(yōu)質(zhì)程度是與rand()函數(shù)相同的。記得我之前題的判斷隨機(jī)數(shù)優(yōu)劣的標(biāo)準(zhǔn)嗎?

  1. 隨機(jī)程度,即隨機(jī)算法是否足夠復(fù)雜,隨機(jī)數(shù)之間會不會存在明顯聯(lián)系。

  2. 分布范圍,即是否存在隨機(jī)數(shù)在分布區(qū)域內(nèi)大量出現(xiàn)偏大偏小的現(xiàn)象。分布是否足夠平均。

  3. 循環(huán)長度,即是否會在大量調(diào)用時很快地出現(xiàn)循環(huán)的情況。

就是這個

我們來逐條分析。

首先,隨機(jī)程度方面,雖然你們之前看過rand()函數(shù)代碼,可能清楚數(shù)字之間的關(guān)聯(lián)
。但在實(shí)際運(yùn)用中,這個數(shù)字之間的關(guān)聯(lián)還是基本可以忽略的。所以在隨機(jī)程度方面,rand()函數(shù)還是能夠勉強(qiáng)通過的。

在平均分布方面,單看代碼可能感覺不出來。

那么,筆者就做一個測試:

#include<iostream>
#include<stdlib.h>
using namespace std ;
int data[1000] ;
int main ( ) {
    for ( long long i = 1 ; i <= 100000000 ; i ++ ){
        int tmp = rand ( ) % 100000 ; //生成一個100000以內(nèi)的隨機(jī)數(shù) 
        data[ tmp / 10 ] ++ ; //統(tǒng)計(jì)出現(xiàn)次數(shù) 
    }
    for ( int i = 1 ; i <= 100 ; i ++ ) {
        cout << data[i] << endl ;
    }
    cout << ' ok ' << endl ;
    return 0 ;
}

最后結(jié)果:

結(jié)果

從中我們可以看到,這個分布還是非常平均的。

循環(huán)長度…

這個主要就是rand()函數(shù)的硬傷了,32768這個長度真的挺不夠用的。在需要大量調(diào)用rand()函數(shù)的算法中(比如退火),基本都會把rand()卡出循環(huán)。

那有沒有既優(yōu)質(zhì)又循環(huán)節(jié)長的算法呢?

梅森旋轉(zhuǎn)算法(MT19337)

這個很重要,所以標(biāo)題升了一級

這個是目前產(chǎn)生優(yōu)質(zhì)偽隨機(jī)數(shù)的普遍算法

在C++11,python等多種語言中都有使用# 旋轉(zhuǎn)算法簡介

梅森旋轉(zhuǎn)算法,也可以寫作MT19937。是有由松本真和西村拓士在1997年開發(fā)的一種能快速產(chǎn)生優(yōu)質(zhì)隨機(jī)數(shù)的算法。

其實(shí)這個算法跟梅森沒有什么關(guān)系,它之所以叫做是梅森旋轉(zhuǎn)算法是因?yàn)樗难h(huán)節(jié)是2^19937-1,這個叫做梅森素?cái)?shù)。

這個算法之所以說是產(chǎn)生優(yōu)質(zhì)隨機(jī)數(shù),是因?yàn)樗谘h(huán)節(jié)特別長的情況下(2^19337-1)還能保證平均分布。

可能有的同學(xué)對這個循環(huán)節(jié)有點(diǎn)質(zhì)疑??赡苡X得2^19937-1有點(diǎn)短?

我在這里大概給一個概念:

銀河系中的恒星數(shù)量級10^11

撒哈拉沙漠中的沙子數(shù)數(shù)量級是10^26

宇宙中目前可觀察的粒子數(shù)量級是10^87

2^19937數(shù)量級是10^6001

這個比較大概心里有數(shù)了吧

相差的已經(jīng)不止是一個數(shù)量級了

同時他在623維中的分布都十分的均勻(這個不用理解)

知道分布平均就好了

梅森

(梅森鎮(zhèn)樓)

->continue

前置知識

分析這個算法的原理需要的前置知識在網(wǎng)上講的都比較繞,我在這里就通俗的科普一下,主要是認(rèn)識這幾個名詞。

(用詞不準(zhǔn)確輕噴)

線性反饋移位寄存器(LFSR)

線性反饋位移寄存器

這個,就當(dāng)它是隨機(jī)數(shù)發(fā)生器就完事了,不要太去糾結(jié)定義。后面會講。

本原多項(xiàng)式

簡單的說來就是沒法化簡的多項(xiàng)式

比如 y=x4+x2 就可以化簡為(x2+1)x2

也是知道就好,不用過于追求定義

計(jì)算機(jī)的一個二進(jìn)制單位(0或1)就是一級

這個應(yīng)該比較好理解

反饋函數(shù)

這個應(yīng)該是網(wǎng)上看別的博客最繞的知識點(diǎn)

簡單地理解成你要對這個寄存器干什么的一個函數(shù)就好了

(看到這里應(yīng)該還沒懵吧)

異或

這個…

還要我科普嗎?

就是兩個數(shù),如果都是0或都是1就輸出0,一個1一個0輸出1.

->continue

原理分析

這個旋轉(zhuǎn)算法實(shí)際上是對一個19937級的二進(jìn)制序列作變換。

首先我們達(dá)成一個共識:

一個長度為n的二進(jìn)制序列,它的排列長度最長為2^n。

當(dāng)然這個也是理論上的,實(shí)際上可能因?yàn)槟承┎僮鞑划?dāng),沒挺到2^n個就開始循環(huán)了。

那么如何將這個序列的排列撐滿2^n個,就是這個旋轉(zhuǎn)算法的精髓。

如果反饋函數(shù)的本身+1是一個本原多項(xiàng)式,那么它的循環(huán)節(jié)達(dá)到最長,即2^n-1

這個數(shù)學(xué)證明本文不作過多論述,有興趣者可以自己查閱資料

個人感覺單講知識點(diǎn)挺難懂的(筆者就是這么被坑的)

我們就拿一個4級的寄存器模擬一下:

我們這里使用的反饋函數(shù)是 y=x^4+x^2+x+1(這個不是本原多項(xiàng)式,只是拿來好理解)

這個式子中x^4,x^2,x的意思就是我們每次對這個二進(jìn)制序列的從后往前數(shù)第4位和第2位做異或運(yùn)算 ,然后x的意思是我們再拿結(jié)果和最后一位做異或運(yùn)算。把最后的結(jié)果放到序列的開頭,整個序列后移一位,最后一位舍棄。

第一步
  1. 初始數(shù)組 { 1 , 0 , 0 , 0 } (為什么不是 0,0,0,0 你們可以自己想想,文章末尾揭曉)

第二步
  1. 將它的第四位和第二位抓出來做異或運(yùn)算

第三步
  1. 把剛剛的運(yùn)算結(jié)果和最后一位再做一次運(yùn)算

第四步
  1. 把最后的運(yùn)算結(jié)果放到第一位,序列后移。最后一位被無情的拋棄

這就是一次運(yùn)算,然后這個算法就是不斷循環(huán)這幾步,從而不斷偽隨機(jī)改變這個序列。

上圖是一個網(wǎng)上找的一個4級寄存器的模擬過程

大家可以推一下,它所使用的反饋函數(shù)(y=x^4+x+1)

因?yàn)檫@個是本原多項(xiàng)式

所以他最后的循環(huán)節(jié)是2^4-1=15

運(yùn)算結(jié)果如下:

結(jié)果

(圖片摘自原文鏈接

大家可以看到這個運(yùn)算結(jié)果包含到了2^4-1~1中的所有數(shù)字,并且沒有循環(huán)。

同時擁有很好的隨機(jī)性。

可能又有人有疑問了:

這個運(yùn)算結(jié)果明明能看出規(guī)律啊,我不是看到了很多1的平行四邊形嗎?

醒醒

這是二進(jìn)制數(shù)。

如果你把它轉(zhuǎn)化成數(shù)字。

8 12 14 15 7 11 …

能看出規(guī)律?

關(guān)于旋轉(zhuǎn)

可能有人到這里還沒看出“旋轉(zhuǎn)”在哪里。

因?yàn)槲覀兠看斡?jì)算出來的結(jié)果會放在開頭,序列后移一位??雌饋砭拖駭?shù)組在向后旋轉(zhuǎn)…

(本來想做gif的,后來不知道怎么做出旋轉(zhuǎn))

大家自行腦補(bǔ)

->continue

算法評價(jià)

1.隨機(jī)程度:

這個應(yīng)該不用說了,認(rèn)真看這個原理的都應(yīng)該清楚它的隨機(jī)程度比rand()不知道高到哪里去了。如果說rand()還能夠用公式表達(dá)的話,這個19337已經(jīng)無法通過算式表達(dá)了。

2.分布范圍:

這里筆者比較懶就不做證明了。有興趣的可以拿上面的代碼自行檢測。

3.循環(huán)長度:

其實(shí)這點(diǎn)我可以直接跳過的。19337算法最不慌的就是循環(huán)長度。2^19337的循環(huán)長度根本不需任何算法。畢竟人家這個算法的循環(huán)長度是與空間大小成指數(shù)級關(guān)系的……

代碼實(shí)現(xiàn)

(筆者很懶,直接搬原代碼出處的代碼)

#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


隨機(jī)種子
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位
    }
}


梅森旋轉(zhuǎn)
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;
    }
}

輸出函數(shù)
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;  //筆者注:y即為產(chǎn)生的隨機(jī)數(shù) 
}

int main()
{
    srand(0);  //設(shè)置隨機(jī)種子
    int cnt = 0;
    for(int i=0; i<1000000; i++)  //下面的循環(huán)是用來判斷隨機(jī)數(shù)的奇偶概率的 
    {
        if(rand() & 1)
            cnt++;
    }
    cout<<cnt / 10000.0<<'%'<<endl;
    return 0;
}

->continue

填一下前面的坑

這里回答一下前面的那個問題:

為什么循環(huán)節(jié)是2^n-1而不是2^n

這個問題的答案和為什么初始序列不能是 { 0 , 0 , 0 , 0 }是一樣的,因?yàn)槿绻?的話,無論怎么異或運(yùn)算都不能產(chǎn)生循環(huán)。那么還怎么偽隨機(jī)啊。

因?yàn)椴荒苁侨?,所以循環(huán)節(jié)要-1

最后非常感謝你能有耐心讀到這里。

本文到這里應(yīng)該就水完結(jié)束了,當(dāng)然,既然你好不容易看到了這里,我就給一個彩蛋吧( 有點(diǎn)勉強(qiáng) )。

關(guān)于rand函數(shù)為什么是用1103515245和12345這兩個數(shù)…你可以理解為玄學(xué)。不過真是原因是用這兩個數(shù)推算出來的的隨機(jī)數(shù)分布相對平均。更符合偽隨機(jī)數(shù)的特性。( 這個我盡力用實(shí)驗(yàn)來論證,目前還在構(gòu)思,也可能正在實(shí)驗(yàn) )

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
PHP的加密偽隨機(jī)數(shù)生成器的使用
用Excel生成隨機(jī)數(shù)(排序用)
c語言中如何隨機(jī)生成數(shù)
純線性同余隨機(jī)數(shù)生成器
淺談隨機(jī)數(shù)發(fā)生器 原創(chuàng) 2013年12月19日 01:51:28 標(biāo)簽:隨機(jī) /隨機(jī)數(shù)
用PHP生成隨機(jī)數(shù)的函數(shù)(代碼示例)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服