孫靈杰 趙曉東 方歡
摘要:該文針對(duì)C++語(yǔ)言中的隨機(jī)數(shù)生成以及使用方法進(jìn)行分析和探討,主要對(duì)各種隨機(jī)數(shù)的生成算法進(jìn)行設(shè)計(jì)。在C++中,隨機(jī)數(shù)的生成主要通過(guò)函數(shù)文件
關(guān)鍵詞:隨機(jī)數(shù);偽隨機(jī)數(shù);種子;隨機(jī)數(shù)生成器
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2017)08-0098-03
1概述
經(jīng)過(guò)對(duì)C++語(yǔ)言的學(xué)習(xí),筆者發(fā)現(xiàn)書中對(duì)于隨機(jī)函數(shù)的使用只是一概而過(guò),沒(méi)有進(jìn)行深入的闡釋和聯(lián)想。文獻(xiàn)是到“其實(shí)計(jì)算機(jī)不會(huì)產(chǎn)生絕對(duì)隨機(jī)的隨機(jī)數(shù),只能產(chǎn)生“偽隨機(jī)數(shù)”。其實(shí)絕對(duì)隨機(jī)的隨機(jī)數(shù)只是一種理想的隨機(jī)數(shù),計(jì)算機(jī)只能生成相對(duì)的隨機(jī)數(shù),即偽隨機(jī)數(shù)。實(shí)際上,系統(tǒng)是將0~32767之間的整數(shù)“隨意”地排成了一個(gè)“隨機(jī)數(shù)表”,程序第一次調(diào)用rand()函數(shù)是取“隨機(jī)數(shù)表”中的第一個(gè),第二次調(diào)用rand()函數(shù)是取“隨機(jī)數(shù)表”的第二個(gè),由此類推。即使我們運(yùn)行了多次,但都是在同一個(gè)系統(tǒng)上,而同一個(gè)系統(tǒng)產(chǎn)生的“隨機(jī)數(shù)表”又始終是相同的,因此每一次運(yùn)行的結(jié)果都是一樣的。”現(xiàn)有文獻(xiàn)大都集中在介紹隨機(jī)函數(shù)的用法,本文從實(shí)際應(yīng)用出發(fā),分析和研究各種不同類型隨機(jī)數(shù)的生成算法,并進(jìn)行實(shí)驗(yàn)分析。
2隨機(jī)數(shù)的生成的原理(C++框架下)
2.1C++中隨機(jī)數(shù)的定義
C++語(yǔ)言中使用cstdlib中的函數(shù)rand()進(jìn)行生成,但生成的只是偽隨機(jī)數(shù)。因?yàn)閞and()的內(nèi)部實(shí)現(xiàn)是用線性同余法做成的,生成隨機(jī)數(shù)時(shí),需要指定一個(gè)種子,用srand()來(lái)設(shè)置rand()產(chǎn)生隨機(jī)數(shù)時(shí)的隨機(jī)數(shù)種子,如果每次srand()都設(shè)相同值,rand()所產(chǎn)生的隨機(jī)數(shù)值每次就會(huì)一樣。通??梢岳胻ime(0)的返回值或NULL來(lái)當(dāng)做seed,這樣可以輸出不同的隨機(jī)數(shù)。
2.2隨機(jī)數(shù)隨機(jī)重現(xiàn)試驗(yàn)
線性同余法產(chǎn)生對(duì)隨機(jī)數(shù)是偽隨機(jī)數(shù),下面進(jìn)行試驗(yàn),測(cè)試具體偽隨機(jī)數(shù)的特點(diǎn)。
通過(guò)圖1的實(shí)驗(yàn)結(jié)果,可以發(fā)現(xiàn)當(dāng)給予相同的隨機(jī)數(shù)函數(shù)種子時(shí),他會(huì)輸出相同的數(shù)字,這就是“偽隨機(jī)數(shù)”名字的來(lái)歷。為了設(shè)計(jì)出不同的隨機(jī)函數(shù),C++引入函數(shù)time(0)(電腦上確切的時(shí)間),用time(0)作為種子,可以實(shí)現(xiàn)隨機(jī)數(shù)函數(shù)每次的種子都不同,從而產(chǎn)生出不同的隨機(jī)數(shù),讓數(shù)字的產(chǎn)生更加接近隨機(jī)。
2.3驗(yàn)證偽隨機(jī)數(shù)是否足夠隨機(jī)的實(shí)驗(yàn)
通過(guò)圖2,由此看出0-9的各個(gè)數(shù)字,當(dāng)隨機(jī)數(shù)數(shù)量足夠多時(shí),產(chǎn)生概率是近似相同的,因此Fang()函數(shù)產(chǎn)生的偽隨機(jī)數(shù)是可以近似看作隨機(jī)數(shù)的。
3隨機(jī)數(shù)常見(jiàn)的使用方法
3.1隨機(jī)數(shù)小數(shù)(不考慮進(jìn)位)的產(chǎn)生
隨機(jī)數(shù)產(chǎn)生器rand()是根據(jù)其后%n中的n來(lái)確定產(chǎn)生的數(shù)字的,會(huì)產(chǎn)生出所有小于n的整形數(shù)字(包括0),由于c++語(yǔ)言中%(取余函數(shù))只能輸出整數(shù),所以隨機(jī)小數(shù)是不能直接產(chǎn)生的,必須運(yùn)用其他方式。
從圖3可以看出,雖然rand()函數(shù)只能輸出整數(shù),但通過(guò)除法運(yùn)算,可以輸出小數(shù),再加上整數(shù)就可以輸出具有大于1的隨機(jī)小數(shù),通過(guò)實(shí)驗(yàn)結(jié)果可以證明算法的正確性。
3.2隨機(jī)數(shù)小數(shù)(考慮進(jìn)位)的產(chǎn)生
通過(guò)對(duì)rand()函數(shù)產(chǎn)生數(shù)據(jù)的數(shù)字類型變換從而為浮點(diǎn)數(shù)創(chuàng)造了可能,/10可以制造出一位小數(shù),/100可以制造出兩位小數(shù),如果想隨機(jī)輸出3-5之間的小數(shù)只需要將%n中的n改為大于10的數(shù)字,通過(guò)小數(shù)點(diǎn)進(jìn)位的方式來(lái)進(jìn)行。例如:
圖4這為小數(shù)隨機(jī)數(shù)(跨位數(shù))的生成算法。
分析:關(guān)于進(jìn)位,可以看做是大于1的小數(shù)和整數(shù)的相加,通過(guò)rand()隨機(jī)輸出0-20的隨機(jī)數(shù),除以10后,便成為隨機(jī)輸出0.0-2.0之間的隨機(jī)小數(shù),加上3后成為隨機(jī)輸出3.0-5.0之間的隨機(jī)數(shù),根據(jù)實(shí)驗(yàn)結(jié)果,這種算法正確。
3.3任意數(shù)的隨機(jī)輸出
C++中rand()只能通過(guò)取余函數(shù)來(lái)進(jìn)行模擬,如果要隨機(jī)出特定的隨機(jī)數(shù),譬如1、4、5、9這四個(gè)隨機(jī)數(shù),我們可以通過(guò)if來(lái)進(jìn)行篩選。
分析:隨機(jī)數(shù)只能連續(xù)輸出,如果要輸出特定的數(shù)字只能依靠if判斷語(yǔ)句,進(jìn)行隨機(jī)數(shù)的篩選,如果是特定的數(shù)字就輸出,不是就繼續(xù)隨機(jī)輸出下一個(gè)數(shù)字。通過(guò)圖實(shí)驗(yàn)結(jié)果證明這種算法正確。
3.4不同比例隨機(jī)數(shù)輸出
在實(shí)際生活中隨機(jī)數(shù)的輸出概率并不均等,那么依靠c++語(yǔ)言中,運(yùn)用rand()函數(shù)仍可以進(jìn)行輸出,例如0、1、2、3、4、5、6這些數(shù)字,而0、1、2、3這三個(gè)數(shù)字比其他數(shù)字更容易輸出50%。
分析:第一個(gè)for循環(huán)按等比例輸出隨機(jī)數(shù),第二個(gè)for循環(huán)通過(guò)再次隨機(jī)輸出特定相同數(shù)字相同的次數(shù),通過(guò)判斷語(yǔ)句,只打印比例多出來(lái)的數(shù)字,從而使特定數(shù)字多出50%的概率輸出,通過(guò)實(shí)驗(yàn)結(jié)果,得出這種算法是正確的。
3.5任意0、1串的輸出
在實(shí)際編程操作中,很多時(shí)候都要運(yùn)用0、1串的輸出。
分析:運(yùn)用for()循環(huán)進(jìn)行具體次數(shù)的輸出使字符串的輸出更加方便。
4小結(jié)
我們?cè)谏钪幸矔?huì)遇到很多有關(guān)隨機(jī)數(shù)的問(wèn)題,如隨機(jī)抽獎(jiǎng),隨機(jī)點(diǎn)名等等。本文介紹了c++中隨機(jī)數(shù)的使用以及產(chǎn)生帶小數(shù)的隨機(jī)數(shù),進(jìn)位的隨機(jī)小數(shù),隨機(jī)輸出不連續(xù)的數(shù)字,輸出不同概率的隨機(jī)數(shù)以及一種可以解微積分的方法,對(duì)一些實(shí)例進(jìn)行了較為詳細(xì)的解釋,并對(duì)結(jié)果進(jìn)行了分析,有助于更好的使用隨機(jī)數(shù)函數(shù),為現(xiàn)實(shí)生活中解決隨機(jī)數(shù)函數(shù)問(wèn)題打下現(xiàn)實(shí)基礎(chǔ)。