C++標準庫:random

sgqmax發表於2024-11-01

隨機數生成裝置

隨機數生成裝置random_device,生成非確定性隨機數,在Linux中透過讀取/dev/urandom裝置,Windows中使用rand_s

過載了()運算子,每次呼叫會生成一個min()max()之間的高質量隨機數種子,若在Linux(Unix Like)下,可以使用這個生成高質量的隨機數,可以理解為真隨機數,windows下就無所謂了

隨機數引擎類

  • 由編譯器廠家實現
    default_random_engine
  • 線性同餘引擎演算法
    linear_congruential_engine
  • 梅森旋轉演算法
    mersenne_twister_engine
  • 帶進位的線性同餘演算法
    subtract_with_carry_engine
  • 基於梅森旋轉演算法
    生成周期更長的偽隨機數,質量高,但是速度較慢
    std::mt19937
    std::mt19937_64 64 bit 版本

除了使用random_device,還可以用time()生成隨機數種子

default_random_engine dre(time(NULL));

由於time()返回以秒計的時間,該方式只適用於生成種子的間隔為秒級或更長的場景

隨機數分佈類

將隨機數引擎生成的隨機數序列對映到常見的分佈

  • 均勻分佈
    std::uniform_int_distribution<>
    整數均勻分佈,若使用無參構造,則範圍為[0,numberic_limits::max()]
    std::uniform_real_distribution<>
    浮點數均勻分佈,預設為double,若使用無參構造,則範圍為[0,1)
  • 伯努利型別
    伯努利分佈std::bernoulli_distribution
    二項分佈std::binomial_distribution
    幾何分佈std::geometry_distribution
    負二項分佈std::negative_biomial_distribution
  • 正態分佈相關
    正態分佈std::normal_distribution<>
    卡方分佈chi_squared_distribution
    柯西分佈cauchy_distribution
    費歇爾F分佈fisher_f_distribution
    t分佈student_t_distribution
  • 分段分佈
    離散分佈discrete_distribution
    分段常數分佈piecewise_constant_distribution
    分段線性分佈piecewise_linear_distribution
  • 其他分佈
    泊松分佈poisson_distribution
    指數分佈exponential_distribution
    伽馬分佈gamma_distribution
    威布林分佈weibull_distribution
    極值分佈extreme_value_distribution

如下函式,用於生成隨機數

vector<unsigned> bad_randVec() {
    default_random_engine engine;
    uniform_int_distribution<unsigned> ui_distr(0,9);
    vector<unsigned> ret;
    for(size_t i = 0;i<100;i++)
        ret.push_back(ui_distr(engine));
    return ret;
}

每次呼叫bad_randVec()函式時,都會生成相同的隨機數,若想每次呼叫該函式能獲取到不同的隨機數,應將engineui_distr定義為static,保持變數狀態,從而每次呼叫都生成新的隨機數,如下good_randVec()

vector<unsigned> good_randVec() {
    static default_random_engine engine;
    static uniform_int_distribution<unsigned> ui_distr(0,9);
    vector<unsigned> ret;
    for(size_t i = 0; i<100;i++)
        ret.push_back(ui_distr(engine));
    return ret;
}

示例如下

#include<random>
#include<ctime>
#include<functional>

int main() {
    // std::random_device rd;
    // std::default_random_engine eng(rd());

    // std::default_random_engine eng(1);

    std::default_random_engine eng(time(NULL));

    std::uniform_int_distribution<int> distr(1,10);

    auto func= bind(distr, eng);
    for(int i=0; i<10; ++i){
        std::cout<<func()<<std::ends; // distr(eng);
    }

    return 0;
}

注:若想在類中初始化uniform_int_distribution,可在建構函式初始化列表中進行

相關文章