6

このプログラムの出力を見て驚いた:

#include <iostream>
#include <random>

int main()
{
    std::mt19937 rng1;
    std::mt19937 rng2;
    std::uniform_real_distribution<double> dist;

    double random = dist(rng1);
    rng2.discard(2);

    std::cout << (rng1() - rng2()) << "\n";

    return 0;
}

is 0- つまり、 2 つのstd::uniform_real_distribution乱数を使用して範囲 [0,1) の乱数を生成します。1つ生成してそれを再スケーリングするだけだと思いました。考えてみると、これは32ビットのintを生成し、doubleがこのサイズの2倍であるため、「十分にランダム」ではないためだと思います。doublestd::mt19937

質問: 乱数ジェネレーターと浮動小数点型が任意の型である場合、この数値を一般的に調べるにはどうすればよいですか?

std::generate_canonical編集: [0,1) の乱数のみに関心があるため、代わりに使用できることに気付きました。これが違いを生むかどうかはわかりません。

4

1 に答える 1

2

標準 (セクション27.5.7.2 template<class RealType, size_t bits, class URNG> std::generate_canonical) では、一様乱数発生器 (URNG) の呼び出し回数が次のように明示的に定義されています。

max(1, b / log_2 R),

ここで、b は、RealType の仮数部のビット数と、テンプレート パラメータとして generate_canonical に指定されたビット数の最小値です。R は、URNG が返すことができる数値の範囲です(URNG::max()-URNG::min()+1)。ただし、あなたの例では、倍精度の仮数部の 53 ビットを埋めるために mt19937 を 2 回呼び出す必要があるため、これは違いはありません。

他の分布の場合、標準では、URNG が分布の 1 つの数値を取得するために生成する必要がある数値に関する情報を取得する一般的な方法は提供されていません。

その理由は、一部の分布では、分布の単一の数を生成するために必要な一様乱数の数が固定されておらず、呼び出しごとに異なる可能性があるためです。例は ですstd::poisson_distribution。これは通常、これらの数値の積が特定のしきい値に達するまで、各反復で一様乱数を描画するループとして実装されます (たとえば、GNU C++ ライブラリの実装(1523 ~ 1528 行) を参照)。 .

于 2013-07-27T09:06:05.167 に答える