6

シミュレーションにブーストmt19937実装を使用しています。

シミュレーションは再現可能である必要があります。つまり、後でRNGシードを保存して再利用する可能性があります。シードの外部ソースが必要であり、ランダム性の特定の保証のためではないため、Windows暗号化APIを使用してシード値を生成しています。シミュレーション実行の出力には、RNGシードを含むメモが含まれるため、シードは適度に短くする必要があります。一方、シミュレーションの分析の一環として、いくつかの実行を比較しますが、これらの実行が実際に異なることを確認するには、異なるシードを使用する必要があるため、シードは十分に長くする必要があります偶発的な衝突を避けるため

64ビットのシードで十分であると判断しました。衝突の可能性は、約2 ^ 32回の実行後に50%に達します。その確率は十分に低いため、それによって引き起こされる平均誤差は私には無視できます。32ビットのシードを使用するのは難しいです。衝突の可能性は、2 ^ 16の実行後にすでに50%に達します。それは私の好みには少しありそうです。

残念ながら、ブーストの実装は、完全な状態ベクトル(遠い、長すぎる)をシードするか、単一の32ビットのunsignedlongをシードします。これは理想的ではありません。

32ビット以上で完全な状態ベクトル未満のジェネレーターをシードするにはどうすればよいですか?ベクトルをパディングするか、シードを繰り返して状態ベクトルを埋めようとしましたが、結果をざっと見ただけでも、結果が良くないことがわかります。

4

2 に答える 2

3

mersenne_twisterテンプレートのブーストソースを見てください:

  void seed(UIntType value)
  {
    // New seeding algorithm from 
    // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
    // In the previous versions, MSBs of the seed affected only MSBs of the
    // state x[].
    const UIntType mask = ~0u;
    x[0] = value & mask;
    for (i = 1; i < n; i++) {
      // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
      x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
    }
  }

mt19937UIntTypeの場合uint32_twは32です。64ビットシードの場合、そのアルゴリズムを使用して、下位32ビットを使用して状態のすべての偶数インデックス(x)を計算し、上位32ビットを使用して状態の奇数インデックスを計算できます。

(これはカーゴカルトの提案ですが)

于 2010-05-26T22:40:30.370 に答える
3

あなたの仮定は間違っています。シミュレーションの場合、暗号的に強力なシードは必要ありません。実際、シード 1、2、3、4 などを使用する方がよい場合がよくあります。Mersenne Twister の出力値には相関がありませんが、希望するシミュレーション出力を得るために種を厳選したかどうかについて誰も疑問を抱くことはありません。

本当の必要性を持っている他の人にとって、1 つの簡単な方法は、生成された最初の (シード>>32) 値を破棄することです。これにより、状態の約 log2(seed>>32) 余分なビットが得られます。ただし、いくつかの余分なビットが必要な場合にのみ効率的に機能します. この方法で 32 ビットを追加するのは、おそらく遅すぎます。

より高速なアルゴリズムは、適切な乱数発生器の完全な状態ベクトルを生成することです。質問で言及されているソリューション (繰り返しまたはパディング) は、結果の状態ベクトルのランダム性が制限されているため、あまり良くありません。しかし、 の出力から初期状態ベクトルを埋める場合mersenne_twister(seed1) ^ mersenne_twister(seed2)、これはまったく問題になりません。

于 2010-05-27T09:33:51.640 に答える