std::seed_seq::generate
template< class RandomIt > void generate( RandomIt begin, RandomIt end ); |
(C++11以上) | |
この seed_seq
のコンストラクタに元々提供されたデータを基にして、範囲 [begin, end) を符号なし整数値 i
(0 ≤ i < 232
) ��埋めます。 生成される値は、初期値が強くバイアスされていたとしても、32ビットの範囲全体に均等に分布されます。
以下のアルゴリズム (松本眞と西村拓士によるメルセンヌ・ツイスタの初期化シーケンスをベースに、2007年の斎藤睦夫によって行われた改善を取り込んだもの) が使用されます。
- begin == end の場合は、何もしません。 そうでなければ、
- まず、出力範囲の各要素を値 0x8b8b8b8b に設定します。
- 以下のアルゴリズムに従って、出力範囲の要素を変換します。
For k = 0,..., m-1
where m=max(s+1, n)
and n=end-begin
and s=v.size()
and v is the private container holding the values originally provided by the constructor of this seed_seq
object,
- begin[k+p] += r1
- begin[k+q] += r2
- begin[k] = r2,
where p=(n-t)/2
and q=p+t
and t=(n >= 623) ? 11 : (n >= 68) ? 7 : (n >= 39) ? 5 : (n >= 7) ? 3 : (n - 1) / 2
and r1=1664525 * T(begin[k]^begin[k+p]^begin[k−1])
and T(x) = x ^ (x >> 27)
and r2=r1+s if k==0, r2=r1 + k%n + v[k-1] if 0<k<=s, r2=r1 + k%n if k>s.
For k = m,..., m+n-1,
- begin[k+p] ^= r3
- begin[k+q] ^= r4
- begin[k]=r4
where r3 = 1566083941 * T(begin[k]+begin[k+p]+begin[k-1])
and r4=r3 - k%n
ただし、すべての計算は modulo 232
で行われ、出力範囲のインデックスアクセス (begin[x]) は modulo n が取られます。
目次 |
[編集] 引数
begin, end | - | std::iterator_traits<>::value_type が32ビット値を格納するのに適した符号なし整数型である可変ランダムアクセスイテレータ |
型の要件 | ||
-RandomIt は LegacyRandomAccessIterator の要件を満たさなければなりません。
|
[編集] 戻り値
なし。 結果は [begin, end) の範囲に書き込まれます。
[編集] 例外
begin
または end
の操作が例外を投げる場合に限り投げます。
[編集] 例
#include <random> #include <iostream> int main() { std::seed_seq seq({1,2,3,4,5}); std::vector<std::uint32_t> seeds(10); seq.generate(seeds.begin(), seeds.end()); // Step 1: fill with 0x8b8b8b8b // seeds = {2341178251, 2341178251, 2341178251, 2341178251, 2341178251, // 2341178251, 2341178251, 2341178251, 2341178251, 2341178251 } // // Step 2: // n = 10, s = 5, t = 3, p = 3, q = 6, m = 10 // // First iteration, k = 0; r1 = 1371501266, r2 = 1371501271 // // seeds = {1371501271, 2341178251, 2341178251, 3712679517, 2341178251, // 2341178251, 3712679522, 2341178251, 2341178251, 2341178251 } // // Iterations from k = 1 to k = 5 (r2 = r1 + k%n + v[k-1]) // // r1 = 2786190137, 3204727651, 4173325571, 1979226628, 401983366 // r2 = 2786190139, 3204727655, 4173325577, 1979226636, 401983376 // // seeds = {3350727907, 3188173515, 3204727655, 4173325577, 1979226636, // 401983376, 3591037797, 2811627722, 1652921976, 2219536532 } // // Iterations from k = 6 to k = 9 (r2 = r1 + k%n) // // r1 = 2718637909, 1378394210, 2297813071, 1608643617 // r2 = 2718637915, 1378394217, 2297813079, 1608643626 // // seeds = { 434154821, 1191019290, 3237041891, 1256752498, 4277039715, // 2010627002, 2718637915, 1378394217, 2297813079, 1608643626 } // // Step 3 // iterations from k = 10 to k = 19, using ^= to modify the output // // r1 = 1615303485, 3210438310, 893477041, 2884072672, 1918321961, // r2 = 1615303485, 3210438309, 893477039, 2884072669, 1918321957 // // seeds = { 303093272, 3210438309, 893477039, 2884072669, 1918321957, // 1117182731, 1772877958, 2669970405, 3182737656, 4094066935 } // // r1 = 423054846, 46783064, 3904109085, 1534123446, 1495905687 // r2 = 423054841, 46783058, 3904109078, 1534123438, 1495905678 // // seeds = { 4204997637, 4246533866, 1856049002, 1129615051, 690460811, // 1075771511, 46783058, 3904109078, 1534123438, 1495905678 } for(std::uint32_t n : seeds) std::cout << n << '\n'; }
出力:
4204997637 4246533866 1856049002 1129615051 690460811 1075771511 46783058 3904109078 1534123438 1495905678