疑似乱数生成器の内部状態を保存する方法

疑似乱数生成器の内部状態を保存する方法

解説

C++の<random>ヘッダを用いると、mersenne_twister_engineを含むいくつかの疑似乱数生成アルゴリズムを利用できます。疑似乱数生成アルゴリズムは、seed(初期値)に基づいて、決定論的に次の疑似乱数を生成し、呼び出すたびに内部状態が更新されます。そのため、内部状態を保存(シリアライズ)し復元(デシリアライズ)すれば、計算を途中で中断しても、再開時に同じ乱数列が得られます。

それぞれの疑似乱数生成器のクラスには非メンバ関数として、operator==operator<<operator>>が定義されています。

  • operator==
    • 疑似乱数生成器の内部状態を比較する。
  • operator<<
    • 疑似乱数生成器の内部状態をstreamに出力する。
  • operator>>
    • streamから内部状態を読み込む。

operator<<でクラス内の状態を保存し、operator>>で読み込み、operator==で同じ値を持っているか確認することができます。

sample code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <fstream>
#include <random>

using namespace std;

int main() {

//seedの設定
random_device seed_gen; //seedを生成
mt19937 rand_gen1(seed_gen()); //seedを設定

// mt19937の内部状態を保存
ofstream ofs("mt_state.bin");
ofs << rand_gen1;
ofs.close();

// mt19937の内部状態を読み込み->rand_gen2
ifstream ifs("mt_state.bin");
mt19937 rand_gen2;
ifs >> rand_gen2;
ifs.close();

    
//rand_gen1とrand_gen2が等しいかどうかを確認
cout << boolalpha << (rand_gen1 == rand_gen2) << endl;
//一致すればtrue、異なればfalseが出力される
}

参考文献