web-dev-qa-db-ja.com

メルセンヌツイスターC ++を使用して数値(0,1)を生成する

RコードをC++に実装して高速に実行できるように取り組んでいますが、メルセンヌツイスターの実装に問題があります。 (0,1)の間の値のみを生成したい。これが私がこの質問に関係するものです。

#include <random>

std::mt19937 generator (123);

std::cout << "Random value: " << generator() << std:: endl;

Rand_MAXで除算しようとしましたが、探していた値が生成されませんでした。

前もって感謝します。

9
user3508622

C++ 11では、「(疑似)ランダムジェネレーター」と「確率分布」の概念が分離されていますが、これには正当な理由があります。

あなたが望むことは、次の行で達成することができます:

  std::mt19937 generator (123);
  std::uniform_real_distribution<double> dis(0.0, 1.0);

  double randomRealBetweenZeroAndOne = dis(generator);

この分離が必要な理由と、ジェネレーターの出力で標準の分割/範囲操作を使用することが悪い考えである理由を理解したい場合は、これを見てください ビデオ

16
sbabbi

次のようなコードを検討することをお勧めします。

_// For pseudo-random number generators and distributions
#include <random> 

...

// Use random_device to generate a seed for Mersenne twister engine.
std::random_device rd{};    

// Use Mersenne twister engine to generate pseudo-random numbers.
std::mt19937 engine{rd()};

// "Filter" MT engine's output to generate pseudo-random double values,
// **uniformly distributed** on the closed interval [0, 1].
// (Note that the range is [inclusive, inclusive].)
std::uniform_real_distribution<double> dist{0.0, 1.0};

// Generate pseudo-random number.
double x = dist(engine);
_

C++で疑似乱数を生成する方法の詳細(Rand()notが適切でない理由を含む)については、Stephan T. Lavavej(from Going Native 201 ):

Rand()有害と見なされる

7
Mr.C64

std :: mt19937は、Rand()のように0からRand_MAXの間ではなく、0から2 ^ 32-1の間で生成されます。

ちなみに、このクラスはmin()とmax()の値を提供します!

値をdoubleに変換し、min()を減算して、max()-min()で除算する必要があります。

uint32_t val;
val << generator;
double doubleval = ((double)val - generator::min())/(generator::max()-generator::min());

または(あまり一般的ではない)

uint32_t val;
val << generator;
double doubleval = (double)val * (1.0 / std::numeric_limits<std::uint32_t>::max());
1
galinette