美國網(wǎng)站服務(wù)器營銷活動推廣策劃
c++語言中可以用rand()函數(shù)生成隨機數(shù),今天來探討一下rand()函數(shù)的基本用法和實際應(yīng)用。
本系列文章共分兩講,今天主要介紹一下偽隨機數(shù)生成的原理,以及在偽隨機數(shù)生成的基礎(chǔ)上,生成隨機數(shù)的技巧,下一講主要介紹無重復(fù)隨機數(shù)生成的方法和舒爾特方格數(shù)字生成的實例。本文采用循序漸進的方式逐步介紹,并且貼上了實際測試的代碼和結(jié)果。有不詳和不實之處,請各位大神批評指正。
?
目錄
一、rand()函數(shù)的幾個要點
1、rand()函數(shù)所在庫
2、rand()函數(shù)的范圍
3、rand()函數(shù)為偽隨機數(shù)
4、線性同余算法簡介
二、rand()函數(shù)的基本使用技巧
1、單獨使用
2、配合srand()函數(shù)使用
(1)srand()函數(shù)原型
(2)所在庫也是cstdlib
(3)srand()的作用
3、配合time()或getpid()使用
(1)time(NULL)函數(shù)
(2)getpid()函數(shù)
三、rand()函數(shù)的擴展功能
1、生成0~n(n>1)隨機整數(shù)
2、生成n~m(n1)范圍內(nèi)的隨機整數(shù),m-n>
一、rand()函數(shù)的幾個要點
1、rand()函數(shù)所在庫
rand()函數(shù)原型:int rand(void);?
所在的庫為cstdlib,所以使用時需要引入cstdlib頭文件。
2、rand()函數(shù)的范圍
當為int型時,隨機數(shù)的范圍為0~32767。
3、rand()函數(shù)為偽隨機數(shù)
rand()的內(nèi)部實現(xiàn)是用線性同余法做的,它不是真的隨機數(shù),因其周期特別長,故在一定的范圍里可看成是隨機的。
4、線性同余算法簡介
線性同余算法是一種迭代算法,每次迭代計算出的結(jié)果就是偽隨機數(shù),其迭代公式為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1)? ? ? ? ? ? ? ? ? ? ??
式中:
為第
次迭代值;
為第
次迭代值;
、
為常數(shù);
為隨機數(shù)范圍(由rand()數(shù)據(jù)類型確定,如果為int,則為32768);
公式第一次迭代
所用的為初始值,也稱為種子(seed),也就是當
、
、
都確定后,隨機數(shù)的序列是由
值決定的,而系統(tǒng)默認其值為1。
二、rand()函數(shù)的基本使用技巧
1、單獨使用
單獨使用rand()函數(shù)示例代碼如下:
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;int main()
{while(1){cout<<rand()<<endl;Sleep(1000); }
}
經(jīng)過多次測試,發(fā)現(xiàn)這樣一個規(guī)律,每次運行程序時,產(chǎn)生的隨機數(shù)序列都是一樣的,都固定不變?yōu)閇41,18467,6334,26500,...],如下圖所示。因為我們在程序中沒有設(shè)定,而系統(tǒng)默認值為1,所以根據(jù)(1)式算出來的為隨機數(shù)序列值都是一樣的。
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
5705
28145
23281
16827
9961
491
2、配合srand()函數(shù)使用
(1)srand()函數(shù)原型
void srand (usigned int seed)
(2)所在庫也是cstdlib
(3)srand()的作用
用來設(shè)置rand()產(chǎn)生隨機數(shù)時的隨機數(shù)種子。參數(shù)seed是整數(shù),當改變seed值時,產(chǎn)生的偽隨機數(shù)序列就會發(fā)生改變。在程序中設(shè)定seed=0,如下所示。
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;int main()
{while(1){srand(0);cout<<rand()<<endl;Sleep(1000); }
}
運行程序后,發(fā)現(xiàn)偽隨機數(shù)序列發(fā)生變化了,如下圖所示。
38
7719
21238
2437
8855
11797
8365
32285
10450
30612
3、配合time()或getpid()使用
使用srand()函數(shù),改變seed數(shù)值,可以改變偽隨機數(shù)的序列。每次要想生成不同的偽隨機數(shù)序列,就要手動改變seed值,也不是很方便。所以,最好的辦法是每次運行程序,seed值都可以自動改變。通??梢岳胻ime(NULL)或getpid()的返回值作為seed。
(1)time(NULL)函數(shù)
time(NULL)的返回值為當前時間的時間戳(以秒為單位),比如2023-8-2 17:19:04對應(yīng)的時間戳數(shù)值為1690967944。所以每次運行時間不一樣,通過srand()函數(shù)給rand()函數(shù)設(shè)定的seed的值也不一樣,因此產(chǎn)生的隨機數(shù)序列也就不一樣了。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <windows.h>using namespace std;int main()
{srand(time(NULL));while(1){cout<<rand()<<endl;Sleep(1000);}}
下邊是兩次運行的結(jié)果,可見產(chǎn)生的隨機序列不一樣了。
28572
10647
18752
10924
2469
21939
7821
17697
30059
16936
9742
13113
23443
17313
28729
2282
24264
19083
6048
13814
26147
8260
3416
16741
2642
15228
4765
25104
30495
26600
(2)getpid()函數(shù)
getpid是一種函數(shù),功能是取得進程識別碼,許多程序利用取到的此值來建立臨時文件,以避免臨時文件相同帶來的問題。
getpid()函數(shù)需要引入的頭文件有stdio.h、unistd.h和sys/types.h。
調(diào)試程序代碼如下:
#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;int main()
{srand(getpid());while(1){cout<<rand()<<endl;Sleep(1000); }
}
分別執(zhí)行兩次程序生成的偽代碼隨機數(shù)序列也不相同,結(jié)果如下:
5721
5487
18939
28251
29922
6470
2914
16807
14781
32440
28228
15685
28899
30711
4193
17378
25105
4253
4132
15548
3930
16509
23440
17039
getpid函數(shù)與time(NULL)函數(shù)不同之處是:
第一、time(NULL)獲取的是時間戳值,所以與程序的進程無關(guān),無論進程相同還是不同,只要調(diào)取函數(shù)的時間不一樣,那么生成的seed值就不一樣。
第二、getpid函數(shù)是程序的進程識別碼,所以在同一個程序的進程內(nèi)多次調(diào)用函數(shù),生成的seed值是一樣的。只有在不同的進程內(nèi)調(diào)用,seed值才會改變。
三、rand()函數(shù)的擴展功能
1、生成0~n(n>1)隨機整數(shù)
rand()函數(shù)生成的隨機數(shù)范圍為0~32767,那么要想讓范圍變?yōu)?~m(m<32767),只需要用rand()對m+1求余即可。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <windows.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;int main()
{int m;cin>>m;
// srand(getpid());srand(time(NULL));while(1){cout<<rand()%(m+1)<<endl;Sleep(1000);}}
2、生成n~m(n<m,m-n>1)范圍內(nèi)的隨機整數(shù)
要想讓rand()函數(shù)生成的隨機數(shù)范圍為n~m(n<m,m-n>1),只需要用rand()對(m-n+1)求余,再加n即可。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <windows.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;int main()
{int m,n;cin>>n>>m;
// srand(getpid());srand(time(NULL));while(1){cout<<rand()%(m-n+1)+n<<endl;Sleep(1000);}}
(未完待續(xù))