C隨機數
在頭文件<stdlib.h>中有int rand(void)隨機數函數。
- 生成0到RAND_MAX之間的均勻整型數,RAND_MAX是stdlib.h中的宏定義#define RAND_MAX 32767
- 爲了得到特定範圍,通常會對生成的隨機數取餘:rand()%n,rand()%(n-m)+m
- void srand(unsigned int seed)設置隨機數種子,種子不變的情況下,每次調用rand(),都會生成相同的隨機數序列
-
rand()函數每次調用前都會查詢是否調用過srand(seed),如果有那麼它會自動調用srand(seed)一次來初始化它的起始值,若沒有,則使用默認,即srand(1)自動調用它一次
- 使用double(rand())/RAND_MAX可以生成0-1範圍內的隨機浮點數,但精度會有問題,有的數取不到。
C++隨機數
在頭文件<random>中,定義了隨機數引擎類、引擎適配器類和隨機數分佈類。
隨機生成器
隨機種子
隨機數種子設定了一個引擎參數隨機數的初始化狀態,隨機數生成器的狀態由用來計算序列的下一個值的所有數據組成。算法是遞歸的,因此種子會創建一個初始狀態,它被用來生成序列的第一個值;生成的值會改變狀態,然後用它來生成下一個值,以此類推。所以種子的隨機性生成序列的隨機性,可獲得的種子數目會影響可以生成多少種隨機序列。
獲取隨機種子
random_device 類定義的函數對象可以生成用來作爲種子的隨機的無符號整數值。這個類應該使用非確定性數據源,它通常是由操作系統提供的。C++14 標準允許在非確定數據源不可用時,使用隨機數引擎,但在大多數實現中,這沒有必要。非確定性數據源可以是連續敲打鍵盤的時間區間,或者鼠標點擊的區間,或者當前的時鐘時間,或者一些物理特性。
可以按如下方式創建 random_device 對象:
// Generating a succession of 8 seeds
#include <random> // For random_device class
#include <iostream> // For standard streams
int main()
{
std::random_device rd; // A function object for generating seeds
for(size_t n {}; n < 8; ++n)
std::cout << rd() << " ";
std::cout << std::endl;
}
//這段代碼調用 8 次 rd 所表示的函數並輸出它所返回的值。運行上述代碼兩次,得到了下面兩行輸出:
3638171046 3646201712 2185708196 587272045 1669986587 2512598564 1822700048 3845359386
360481879 3886461477 1775290740 2501731026 161066623 1931751494 751233357 3821236773
可以注意到,兩次運行得到的輸出是完全不同的。除了 operator()(),random_device 類只定義了其他的 3 個成員函數。成員函數 min() 和 max() 分別返回的是輸出的最小和最大可能值。如果是用隨機數引擎而不是非確定性數據源實現的,成員函數 entropy() 返回的是將數據源看作 double 或 0 後的熵的估計值。
此處參考:http://c.biancheng.net/view/635.html
可以在創建引擎對象時提供種子,也可以調用引擎對象的seed成員更改種子。
若使用<ctime>中的time()函數作爲種子,則兩次調用間隔需要大於1s,否則會產生相同的隨機序列。,time()返回從特定時刻到現在經過了多少秒,接受唯一參數指定寫入時間的數據結構。
使用形式:default_random_engine e(time(0))
隨機引擎類
default_random_engine //某個引擎的類型別名,指定的默認引擎,常用
三大引擎
liner_congruential_engine
mersenne_twister_engine
subtract_with_carry_engine
三大引擎適配器
discard_block_engine
independent_bits_engine
shuffle_bits_engine
引擎操作
隨機分佈類
均勻分佈
uniform_int_distribution<IntT> u(m, n)
uniform_real_distribution<RealT> u(m, n)
伯努利分佈
bernoulli_distribution b(p)
...
泊松分佈
poisson_distribution<IntT> p(x)
...
指數分佈
exponential_distributon<RealT> e(lam)
...
正太分佈
normal_dietribution<RealT> n(m, s)
...
分佈類型操作
*在希望保持引擎和分佈對象狀態時,可以將他們定義爲static。
參考:C++ primer