Namespaces
Variants

Pseudo-random number generation

From cppreference.net

乱数ライブラリは、乱数および疑似乱数を生成するクラスを提供します。これらのクラスには以下が含まれます:

  • 均一乱数ビット生成器 (URBG)。疑似乱数生成器であり、均一分布で整数列を生成する乱数エンジンと、(利用可能な場合) 真の乱数生成器の両方を含む。
  • 乱数分布 (例: uniform , normal , または poisson distributions )。URBGの出力を様々な統計分布に変換する。

URBGと分布は、ランダムな値を生成するために一緒に使用されるように設計されています。すべての乱数エンジンは、特定のシードで初期化され、シリアライズおよびデシリアライズが可能であり、再現可能なシミュレーターで使用できます。

目次

注記: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Uniform random bit generators、Random number enginesなど)は原文のまま保持しました - HTMLタグ、属性、構造は完全に保持されています - 数値や技術用語は翻訳対象外としました

一様乱数ビット生成器

一様乱数ビット生成器( uniform random bit generator )は、可能な結果の範囲内の各値が(理想的には)等しい確率で返される符号なし整数値を返す関数オブジェクトです。

すべての均一乱数ビット生成器は UniformRandomBitGenerator 要件を満たします。 C++20では uniform_random_bit_generator コンセプトも定義されています。

定義ヘッダ <random>
型がuniform random bit generatorとして適格であることを指定する
(コンセプト)

乱数生成エンジン

ランダム数エンジン(一般に エンジン と略される)は、シードデータをエントロピー源として使用して擬似乱数を生成する均一乱数ビット生成器です。

任意の時点において、型 E のエンジン e は、ある非負整数 i に対する状態 e i を持ちます。構築時には、 e は初期状態 e 0 を持ち、これはエンジンパラメータと初期シード(またはシードシーケンス)によって決定されます。

以下のプロパティは、あらゆるエンジンタイプ E に対して常に定義されています:

  • E の状態の サイズ E::result_type のサイズの倍数、すなわち ( sizeof e i ) / sizeof ( E :: result_type ) )。
  • 遷移アルゴリズム TA によって e の状態 e i が後続状態 e i+1 に進む(すなわち TA ( e i ) == e i+1 )。
  • 生成アルゴリズム GA によって e の状態が E::result_type 型の値にマッピングされ、結果は擬似乱数となる。

擬似乱数シーケンスは、 TA GA を交互に呼び出すことで生成できます。

標準ライブラリは、擬似乱数生成アルゴリズムの3つの異なるクラスの実装をクラステンプレートとして提供しており、アルゴリズムをカスタマイズできるようになっています。使用するエンジンの選択には、いくつかのトレードオフが伴います:

  • 線形合同法エンジン は比較的高速で、状態の保存に必要なストレージが非常に小さい。
  • メルセンヌ・ツイスタエンジン は低速で状態保存の要件も大きいが、適切なパラメータでは最長の非反復シーケンスと(望ましいと定義される特性において)最も好ましいスペクトル特性を持つ。
  • キャリー付き減算エンジン は、高度な算術命令セットを持たないプロセッサ上でも非常に高速に動作するが、状態保存の要件が大きく、スペクトル特性がやや劣る場合がある。
  • Philoxエンジン カウンターベース乱数生成器 です。これは小さな状態と長い周期(2^130以上)を持ち、大規模並列乱数生成を必要とするモンテカルロシミュレーションでの使用を意図しています。ベクトル化と並列化が容易で、GPU最適化ライブラリに実装されています。
(C++26以降)

これらの乱数生成エンジンのいずれも 暗号論的に安全 ではありません。あらゆるセキュアな操作と同様に、この目的には暗号ライブラリを使用すべきです(例: OpenSSL RAND_bytes )。

これらのテンプレートからインスタンス化されるすべての型は、 RandomNumberEngine 要件を満たします。

定義済みヘッダー <random>
線形合同法 を実装
(クラステンプレート)
メルセンヌ・ツイスター アルゴリズムを実装
(クラステンプレート)
減算付きキャリー( 遅延フィボナッチ )アルゴリズムを実装
(クラステンプレート)
カウターベースの並列化可能なジェネレータ
(クラステンプレート)

乱数エンジンアダプタ

乱数エンジンアダプタは、別の乱数エンジンをエントロピー源として使用して擬似乱数を生成します。これらは一般に、基盤となるエンジンのスペクトル特性を変更するために使用されます。

定義済みヘッダ <random>
乱数エンジンの出力の一部を破棄する
(クラステンプレート)
乱数エンジンの出力を指定されたビット数のブロックにパックする
(クラステンプレート)
乱数エンジンの出力を異なる順序で提供する
(クラステンプレート)

定義済み乱数ジェネレータ

いくつかの特定の人気アルゴリズムが事前定義されています。

**翻訳結果:** - HTMLタグ、属性、コードブロック内のテキストは翻訳せず、元のフォーマットを保持 - C++固有の用語(ranlux48_base, subtract_with_carry_engine, uint_fast64_tなど)は翻訳せず - 数値(48, 5, 12)はそのまま保持 - 翻訳対象のテキストのみを日本語化 **翻訳結果:** **注記:** 指定された要件に従い、HTMLタグ、属性、 タグ内のテキスト、C++固有の用語(knuth_b, std::shuffle_order_engine, std::minstd_rand0など)は翻訳せず、元のフォーマットを保持しています。翻訳対象となる自然言語テキストが存在しないため、出力は入力と同一となります。
ヘッダーで定義 <random>
定義
minstd_rand0 (C++11) std:: linear_congruential_engine < std:: uint_fast32_t ,
16807 , 0 , 2147483647 >

1969年にLewis、Goodman、Millerによって発見され、1988年にParkとMillerによって「最小標準」として採用された

minstd_rand (C++11)

std:: linear_congruential_engine < std:: uint_fast32_t ,
48271 , 0 , 2147483647 >
新しい「最小標準」、1993年にPark、Miller、Stockmeyerによって推奨

mt19937 (C++11)

std:: mersenne_twister_engine < std:: uint_fast32_t ,
32 , 624 , 397 , 31 ,
0x9908b0df , 11 ,
0xffffffff , 7 ,
0x9d2c5680 , 15 ,
0xefc60000 , 18 , 1812433253 >
松本眞と西村拓士による32ビットメルセンヌ・ツイスタ、1998年

mt19937_64 (C++11)

std:: mersenne_twister_engine < std:: uint_fast64_t ,
64 , 312 , 156 , 31 ,
0xb5026f5aa96619e9 , 29 ,
0x5555555555555555 , 17 ,
0x71d67fffeda60000 , 37 ,
0xfff7eee000000000 , 43 ,
6364136223846793005 >
松本眞と西村拓士による64ビットメルセンヌ・ツイスタ、2000年

ranlux24_base (C++11) std:: subtract_with_carry_engine < std:: uint_fast32_t , 24 , 10 , 24 >
ranlux48_base (C++11) std:: subtract_with_carry_engine < std:: uint_fast64_t , 48 , 5 , 12 >
ranlux24 (C++11) std:: discard_block_engine < std:: ranlux24_base , 223 , 23 >

マーティン・リュシャーとフレッド・ジェームズによる24ビットRANLUXジェネレータ、1994年

ranlux48 (C++11) std:: discard_block_engine < std:: ranlux48_base , 389 , 11 >

マーティン・リュシャーとフレッド・ジェームズによる48ビットRANLUXジェネレーター、1994年

knuth_b (C++11) std:: shuffle_order_engine < std:: minstd_rand0 , 256 >
knuth_b (C++11) std:: shuffle_order_engine < std:: minstd_rand0 , 256 >
philox4x32 (C++26) std:: philox_engine < std:: uint_fast32_t , 32 , 4 , 10 ,
0xCD9E8D57 , 0x9E3779B9 ,
0xD2511F53 , 0xBB67AE85 >
philox4x64 (C++26) std:: philox_engine < std:: uint_fast64_t , 64 , 4 , 10 ,
0xCA5A826395121157 , 0x9E3779B97F4A7C15 ,
0xD2E7470EE14C6C93 , 0xBB67AE8584CAA73B >
default_random_engine (C++11) 実装定義の RandomNumberEngine

非決定的乱数

std::random_device は非決定的な均一乱数ビット生成器ですが、非決定的な乱数生成がサポートされていない場合、実装は疑似乱数エンジンを使用して std::random_device を実装することが許可されています。

ハードウェアエントロピー源を使用する非決定的乱数生成器
(クラス)

乱数分布

乱数分布は、URBGの出力を後処理し、結果として得られる出力が定義された統計的確率密度関数に従って分布するようにします。

乱数分布は RandomNumberDistribution 要件を満たします。

定義済みヘッダー <random>
一様分布
範囲内で均一に分布する整数値を生成する
(クラステンプレート)
指定範囲に均一に分布する実数値を生成する
(クラステンプレート)
ベルヌーイ分布
Bernoulli分布 に基づく bool 値を生成する
(クラス)
二項分布に従う整数値を生成する binomial distribution
(クラステンプレート)
負の二項分布に従う整数値を生成する negative binomial distribution
(クラステンプレート)
幾何分布 に従う整数値を生成する
(クラステンプレート)
ポアソン分布
整数値を ポアソン分布 に従って生成する
(クラステンプレート)
実数値を 指数分布 に従って生成する
(クラステンプレート)
実数値を ガンマ分布 に従って生成する
(クラステンプレート)
実数値を ワイブル分布 に従って生成する
(クラステンプレート)
実数値を 極値分布 に従って生成する
(クラステンプレート)
正規分布
実数値を 標準正規分布(ガウス分布) に従って生成する
(クラステンプレート)
対数正規分布に従う実数値を生成する lognormal distribution
(クラステンプレート)
実数値を カイ二乗分布 に従って生成する
(クラステンプレート)
Cauchy分布 に従う実数値を生成する
(クラステンプレート)
FisherのF分布 に従う実数値を生成する
(クラステンプレート)
Studentのt分布 に従う実数値を生成する
(クラステンプレート)
標本分布
離散分布で整数値を生成する
(クラステンプレート)
定数部分区間上に分布する実数値を生成する
(クラステンプレート)
定義された部分区間上に分布する実数値を生成する
(クラステンプレート)

ユーティリティ

定義済みヘッダー <random>
指定された精度の実数値を [ 0 , 1 ) に均等に分布させる
(関数テンプレート)
(C++11)
汎用バイアス除去スクランブルシードシーケンスジェネレータ
(クラス)

乱数アルゴリズム

定義済みヘッダー <random>
範囲を一様乱数ビット生成器からの乱数で埋める
(アルゴリズム関数オブジェクト)

C++乱数ライブラリ

上記で説明したエンジンと分布に加えて、C乱数ライブラリの関数と定数も利用可能ですが、推奨されません:

ヘッダーで定義 <cstdlib>
擬似乱数を生成する
(関数)
擬似乱数生成器を初期化する
(関数)
std::rand によって生成可能な最大値
(マクロ定数)

#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <random>
#include <string>
int main()
{
    // 利用可能な場合は実際の乱数値でシード
    std::random_device r;
    // 1から6の間でランダムな平均値を選択
    std::default_random_engine e1(r());
    std::uniform_int_distribution<int> uniform_dist(1, 6);
    int mean = uniform_dist(e1);
    std::cout << "ランダムに選択された平均値: " << mean << '\n';
    // その平均値を中心とした正規分布を生成
    std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937 e2(seed2);
    std::normal_distribution<> normal_dist(mean, 2);
    std::map<int, int> hist;
    for (int n = 0; n != 10000; ++n)
        ++hist[std::round(normal_dist(e2))];
    std::cout << "平均値 " << mean << " を中心とした正規分布:\n"
              << std::fixed << std::setprecision(1);
    for (auto [x, y] : hist)
        std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\n';
}

出力例:

ランダムに選択された平均値: 4
平均値 4 を中心とした正規分布:
-4
-3
-2
-1
 0 *
 1 ***
 2 ******
 3 ********
 4 *********
 5 ********
 6 ******
 7 ***
 8 *
 9
10
11
12

関連項目

C ドキュメント 疑似乱数生成