C++の擬似乱数生成<random>
C++標準ライブラリには、ランダムと擬似乱数を生成するクラスが用意されています.次のようなクラスがあります.乱数生成クラス:乱数エンジン、乱数エンジンアダプタ、および事前定義乱数生成器を含む均一分布整数シーケンスを生成する擬似乱数生成器. 乱数分布クラス:ジェネレータによって生成されたデジタルシーケンスを、均一分布、正規分布、ポアソン分布などの特定の乱数変数分布に従うデジタルシーケンスのオブジェクトに変換します.
乱数エンジン
乱数エンジンは、シードデータをエントロピーソースとして擬似乱数を生成することができる.
ランダムシード:乱数ジェネレータを初期化し、アルゴリズムを使用して反復して乱数を生成します.最も簡単な使い方は、最初の乱数として次の乱数を生成することです.
クラステンプレート
さぎょう
linear_congruential_engine
線形同余アルゴリズムの実現
mersenne_twister_engine
メイソン巻き取りアルゴリズムの実現
subtract_with_carry_engine
帯域進位減少アルゴリズムの実現
ここで、線形同余エンジンは一般的に速く、状態の記憶に対する要求は非常に小さい.遅延フィボナッチ生成器は,先進的な算術命令セットのないプロセッサでは非常に速いが,状態記憶が膨大で,あまり望ましくないスペクトル特性がある場合がある.メイソン巻き付け器は遅く、大きな状態記憶要件を有しているが、正しいパラメータがあれば、最も長い繰り返し不可能なシーケンスがあり、最も望ましいスペクトル特性を有する.
ここでは,線形同余エンジンとメイソン巻き取り器の詳細な実装過程を紹介する.
せんけいへいこうアルゴリズム
線形同余アルゴリズムの実現は比較的簡単で、数学の表現は以下の通りである.
X n + 1 = mod ( ( a ∗ X n + b ) , c ) X_{n+1} =\text{mod}\left(\left(a*X_n+b\right), c\right) Xn+1=mod((a∗Xn+b),c)
しかし、そのパラメータ
このコードは博文から抜粋したものである
メイソン巻き
メイソン巻き取り器の実現過程は複雑である第1段階:初期化され、ランダム種子に基づいて初期のメイソン回転鎖が得られる. 第2段階:既存のメイソン回転チェーンに基づいて回転アルゴリズムを行い、次のサイクルの回転チェーンを取得する. 第3段階:メイソン回転鎖に基づいて乱数を計算する.
そのC++コードは以下のように実現される.
このコードは私たちのネットワークから抜粋され、このブログには原理解析が含まれています.
乱数エンジンアダプタ
乱数エンジンアダプタは、別の乱数エンジンをエントロピー源とする擬似乱数を生成し、乱数エンジンに基づいてより多様性のあるランダムシーケンスを生成する.
クラステンプレート
さぎょう
discard_block_engine
乱数エンジンの出力の一部を破棄
independent_bits_engine
乱数エンジンの出力を指定したビット数のブロックにパッケージ化
shuffle_order_engine
乱数エンジンの出力を異なる順序で送信
事前定義乱数ジェネレータ
必要に応じて、上記の乱数エンジンと乱数エンジンアダプタに基づいて独自の乱数ジェネレータを構築できます.また、C++の標準ライブラリには、古典的な乱数ジェネレータが必要です.
を選択します.
定義#テイギ#
minstd_rand0
std::linear_congruential_engine<:uint_fast32_t>Lewis、GoodmanおよびMillerによって1969年に発見され、ParkおよびMillerによって1988年に「最小基準」として採択された.
minstd_rand
std::linear_congruential_engine<:uint_fast32_t>より新しい「最小基準」は、Park、MillerおよびStockmeyerに1993年に推奨された
mt19937
std::mersenne_twister_engine<:uint_fast32_t> 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15,0 xefc 60000,18,1812433253>32ビットメイソン巻き付け器は、松本と西村によって1998年に設計された.
mt19937_64
std::mersenne_twister_engine<:uint_fast64_t> 0xb5026f5aa96619e9, 29, 0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000, 43,6364136223846793005>64ビットメイソン巻き取り器は、松本と西村が2000年に設計した
ranlux24_base
std::subtract_with_carry_engine<:uint_fast32_t/>
ranlux48_base
std::subtract_with_carry_engine<:uint_fast64_t/>
ranlux24
std::discard_block_engine<:ranlux24_Base>24ビットRANSUXジェネレータは、MartinLüscherとFred Jamesによって1994年に設計された
ranlux48
std::discard_block_engine<:ranlux48_ベース>48ビットRANSUXジェネレータは、MartinLüscherとFred Jamesによって1994年に設計された
knuth_b
std::shuffle_order_engine<:minstd_rand0/>
default_random_engine
インプリメンテーション定義
らんすうぶんぷ
乱数生成器の出力を処理して、出力結果が定義された統計確率密度関数に従って分布するようにする.
きんいつぶんぷ
uniform_int_distribution
1つの範囲で均一に分布する整数値を生成する
uniform_real_distribution
1つの範囲で均一に分布する実数値を生成する
ベルヌーイぶんぷ
bernoulli_distribution
バーヌリー分布上のbool値を生成
binomial_distribution
二項分布の整数値を生成
negative_binomial_distribution
負の二項分布の整数値を生成
geometric_distribution
幾何学的分布の整数値を生成
ポアソンぶんぷ
poisson_distribution
ポアソン分布の整数値を生成
exponential_distribution
指数分布の実数値を生成
gamma_distribution
生成
weibull_distribution
ウィブール分布の実数値を生成
extreme_value_distribution
極値分布の実数値を生成
せいじょうぶんぷ
normal_distribution
標準正規(Gauss)分布上の実数値を生成する
lognormal_distribution
対数正規分布の実数値を生成する
chi_squared_义齿
χ2
cauchy_distribution
コシ分布の実数値を生成
fisher_f_distribution
フィッシャーを生成
student_t_distribution
学生が生まれる
サンプリングぶんぷ
discrete_distribution
離散分布上のランダム整数の生成
piecewise_constant_distribution
常子区間に分布する実数値を生成する
piecewise_linear_distribution
定義されたサブセクション間に分布する実数値を生成
その他のツール
乱数エンジン
乱数エンジンは、シードデータをエントロピーソースとして擬似乱数を生成することができる.
ランダムシード:乱数ジェネレータを初期化し、アルゴリズムを使用して反復して乱数を生成します.最も簡単な使い方は、最初の乱数として次の乱数を生成することです.
クラステンプレート
さぎょう
linear_congruential_engine
線形同余アルゴリズムの実現
mersenne_twister_engine
メイソン巻き取りアルゴリズムの実現
subtract_with_carry_engine
帯域進位減少アルゴリズムの実現
ここで、線形同余エンジンは一般的に速く、状態の記憶に対する要求は非常に小さい.遅延フィボナッチ生成器は,先進的な算術命令セットのないプロセッサでは非常に速いが,状態記憶が膨大で,あまり望ましくないスペクトル特性がある場合がある.メイソン巻き付け器は遅く、大きな状態記憶要件を有しているが、正しいパラメータがあれば、最も長い繰り返し不可能なシーケンスがあり、最も望ましいスペクトル特性を有する.
ここでは,線形同余エンジンとメイソン巻き取り器の詳細な実装過程を紹介する.
せんけいへいこうアルゴリズム
線形同余アルゴリズムの実現は比較的簡単で、数学の表現は以下の通りである.
X n + 1 = mod ( ( a ∗ X n + b ) , c ) X_{n+1} =\text{mod}\left(\left(a*X_n+b\right), c\right) Xn+1=mod((a∗Xn+b),c)
しかし、そのパラメータ
a,b,c
は一定の条件を満たす必要があり、ここでは、ネットワーク上のC++コードの実装を以下に示す.static uint32 prngState = 0;
uint32 init_rand(uint32 seed)
{
//Seed the pseudo-random number generator
prngState += seed;
//Successful processing
return SUCCESS;
}
uint32 _rand(void)
{
uint32 value;
//Use a linear congruential generator (LCG) to update the state of the PRNG
prngState *= 1103515245;
prngState += 12345;
value = (prngState >> 16) & 0x07FF;
prngState *= 1103515245;
prngState += 12345;
value <<= 10;
value |= (prngState >> 16) & 0x03FF;
prngState *= 1103515245;
prngState += 12345;
value <<= 10;
value |= (prngState >> 16) & 0x03FF;
//Return the random value
return value;
}
int32 rand_range(int32 min, int32 max)
{
int32 value;
//Valid parameters?
if (max > min)
{
//Pick up a random value in the given range
value = min + (_rand() % (max - min + 1));
}
else
{
//Use default value
value = min;
}
//Return the random value
return value;
}
このコードは博文から抜粋したものである
メイソン巻き
メイソン巻き取り器の実現過程は複雑である
そのC++コードは以下のように実現される.
#include
#include
#include
#include
using namespace std;
bool isInit;
int index;
int MT[624]; //624 * 32 - 31 = 19937
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
}
}
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;
}
}
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
}
int main()
{
srand(0); //
int cnt = 0;
for(int i=0; i<1000000; i++) //
{
if(rand() & 1)
cnt++;
}
cout<<cnt / 10000.0<<"%"<<endl;
return 0;
}
このコードは私たちのネットワークから抜粋され、このブログには原理解析が含まれています.
乱数エンジンアダプタ
乱数エンジンアダプタは、別の乱数エンジンをエントロピー源とする擬似乱数を生成し、乱数エンジンに基づいてより多様性のあるランダムシーケンスを生成する.
クラステンプレート
さぎょう
discard_block_engine
乱数エンジンの出力の一部を破棄
independent_bits_engine
乱数エンジンの出力を指定したビット数のブロックにパッケージ化
shuffle_order_engine
乱数エンジンの出力を異なる順序で送信
事前定義乱数ジェネレータ
必要に応じて、上記の乱数エンジンと乱数エンジンアダプタに基づいて独自の乱数ジェネレータを構築できます.また、C++の標準ライブラリには、古典的な乱数ジェネレータが必要です.
を選択します.
定義#テイギ#
minstd_rand0
std::linear_congruential_engine<:uint_fast32_t>Lewis、GoodmanおよびMillerによって1969年に発見され、ParkおよびMillerによって1988年に「最小基準」として採択された.
minstd_rand
std::linear_congruential_engine<:uint_fast32_t>より新しい「最小基準」は、Park、MillerおよびStockmeyerに1993年に推奨された
mt19937
std::mersenne_twister_engine<:uint_fast32_t> 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15,0 xefc 60000,18,1812433253>32ビットメイソン巻き付け器は、松本と西村によって1998年に設計された.
mt19937_64
std::mersenne_twister_engine<:uint_fast64_t> 0xb5026f5aa96619e9, 29, 0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000, 43,6364136223846793005>64ビットメイソン巻き取り器は、松本と西村が2000年に設計した
ranlux24_base
std::subtract_with_carry_engine<:uint_fast32_t/>
ranlux48_base
std::subtract_with_carry_engine<:uint_fast64_t/>
ranlux24
std::discard_block_engine<:ranlux24_Base>24ビットRANSUXジェネレータは、MartinLüscherとFred Jamesによって1994年に設計された
ranlux48
std::discard_block_engine<:ranlux48_ベース>48ビットRANSUXジェネレータは、MartinLüscherとFred Jamesによって1994年に設計された
knuth_b
std::shuffle_order_engine<:minstd_rand0/>
default_random_engine
インプリメンテーション定義
らんすうぶんぷ
乱数生成器の出力を処理して、出力結果が定義された統計確率密度関数に従って分布するようにする.
きんいつぶんぷ
uniform_int_distribution
1つの範囲で均一に分布する整数値を生成する
uniform_real_distribution
1つの範囲で均一に分布する実数値を生成する
ベルヌーイぶんぷ
bernoulli_distribution
バーヌリー分布上のbool値を生成
binomial_distribution
二項分布の整数値を生成
negative_binomial_distribution
負の二項分布の整数値を生成
geometric_distribution
幾何学的分布の整数値を生成
ポアソンぶんぷ
poisson_distribution
ポアソン分布の整数値を生成
exponential_distribution
指数分布の実数値を生成
gamma_distribution
生成
weibull_distribution
ウィブール分布の実数値を生成
extreme_value_distribution
極値分布の実数値を生成
せいじょうぶんぷ
normal_distribution
標準正規(Gauss)分布上の実数値を生成する
lognormal_distribution
対数正規分布の実数値を生成する
chi_squared_义齿
χ2
cauchy_distribution
コシ分布の実数値を生成
fisher_f_distribution
フィッシャーを生成
student_t_distribution
学生が生まれる
サンプリングぶんぷ
discrete_distribution
離散分布上のランダム整数の生成
piecewise_constant_distribution
常子区間に分布する実数値を生成する
piecewise_linear_distribution
定義されたサブセクション間に分布する実数値を生成
その他のツール
std::uniform_random_bit_generator
:均一ランダムビットジェネレータは、符号なし整数値を返し、各値が可能な結果の範囲で(理想的に)等しい戻り確率を持つようにする関数オブジェクトである.std::random_device
:ハードウェアエントロピーソースを用いた非確定乱数生成器std::generate_canonical
:乱数生成器で得られたデータを[0,1]に均一に分布させるseed_seq
:汎用的な偏差除去の混同シードシーケンスジェネレータは、シードの多様性を向上させることによってランダムシーケンスの重複出現を低減する