1. ホーム
  2. c++

[解決済み] 範囲から乱整数を生成する

2022-04-22 16:32:23

質問

与えられた範囲(境界値を含む)のランダムな整数を生成する関数が必要です。品質や乱数性についての無理な要求はしませんが、4つの要求があります。

  • 高速であることが必要です。私のプロジェクトでは、何百万(時には何千万)もの乱数を生成する必要があり、現在使用しているジェネレータ関数がボトルネックになっていることが判明しています。
  • 適度に均一であることが必要です(rand()の使用は全く問題ありません)。
  • 最小から最大の範囲は、<0, 1> から <-32727, 32727> までの範囲です。
  • はseedableでなければならない。

現在、以下のようなC++のコードを持っています。

output = min + (rand() * (int)(max - min) / RAND_MAX)

問題は、それが本当に均一ではないことです - rand() = RAND_MAX (Visual C++では1/32727)のときだけ、maxが返されます。これは、最後の値がほとんど返されない <-1, 1> のような小さな範囲では大きな問題です。

そこで、紙とペンを持って、次の式を思いついた((int)(n + 0.5) 整数丸めのトリックをベースにしたものである)。

しかし、まだ一様な分布にはなりません。10000サンプルで繰り返し実行すると、値 -1, 0, 1 に対して 37:50:13 という比率になります。

より良い計算式を教えてください。(あるいは、擬似乱数生成器全体の関数でもかまいません。)

どのように解決するのですか?

高速で、あなたよりいくらかましだが、まだ適切に一様分布していない解決策は、次のとおりです。

output = min + (rand() % static_cast<int>(max - min + 1))

ただし、範囲の大きさが2のべき乗の場合を除く。 このメソッドは 偏った非一様な分布 の品質にかかわらず rand() . このメソッドの品質を総合的にテストするには 読む .