• 締切済み

メルセンヌ・ツイスタの乱数生成範囲指定(C++)

メルセンヌ・ツイスタで乱数の生成範囲を指定したいのですが 以下の方法以外でもっと厳密に乱数を生成できる方法がわかる方いますか? int n; n = genrand_int32() % 10; 上記では0~9までの乱数を求める事が出来ますが、余りは下二桁のみに依存するので 精度が低いのでは?と考えます。 分かる方いましたら宜しくお願いします。

みんなの回答

回答No.6

ANo.1 にあるとおり、C++なら一様分布が簡単に作れます。 #include <iostream> #include <random> int main() { // メルセンヌ・ツイスター std::mt19937 generator; // 0..9 一様分布 std::uniform_int_distribution<int> distribution(0,9); for (int i = 0; i < 20; ++i) { int number = distribution(generator); std::cout << number << ' '; } }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

全部整数で計算するなら「0以上 Max未満の一様乱数値を (Max/n) で割った値」は n になる可能性がありますね>#3. ただ, 果てしなく厳密にいいだすと「そもそもメルセンヌツイスターで得られる値は完全に一様な分布をするのか」って問題があっちゃったりしますが.

回答No.4

#3の回答ですが、 > 0以上Max未満の一様整数乱数から、 0以上n未満の一様整数乱数を作る方法は > (1) n で割った余り > (2) (Max/n)で割った商 > の二つが主なものです。 これだと、一様乱数にはならないですよね。 (1)で一様乱数を作るには、arc4random_uniformでやっているようなテクニックが必要です。 http://www.opensource.apple.com/source/OpenSSH/OpenSSH-166/openssh/openbsd-compat/bsd-arc4random.c つまり、一様乱数であることを崩す値を捨てます。 (2)についても、整数でやっているとしたら、わり算の余りを切り落としているのでやはり一様にはならないと思います。 あと、MTでやるとしたら、浮動小数点演算が入っても良いなら、genrand_real2()やgenrand_res53()と10を掛けて、小数点以下切り捨てではないでしょうか。 普通は浮動小数点演算を嫌って、arc4random_uniform的なやり方でやるかと思いますが。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

0以上Max未満の一様整数乱数から、 0以上n未満の一様整数乱数を作る方法は (1) n で割った余り (2) (Max/n)で割った商 の二つが主なものです。 > 上記では0~9までの乱数を求める事が出来ますが、余りは下二桁のみに依存するので > 精度が低いのでは?と考えます。 それは、乱数の発生方法によります。 確かに、線形合同法等は短周期のパターンが出やすいことで知られています。 資料によれば、MTは、かなりの長周期で、その中のどこを取っても偏りの少ないことが知られています。

  • maiko0318
  • ベストアンサー率21% (1483/6969)
回答No.2

>厳密に乱数を生成できる方法 >精度が低いのでは? 何をもってそう思われますか? 実行環境があるなら10万回ほど実行して散布表を作ってみてはどうですか? 偏りがなければいいんでしょ?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「余りは下二桁のみに依存する」ってどういうことなんだろう.

参考URL:
http://www.cplusplus.com/reference/random/uniform_int_distribution/