3

私はモンテカルロ シミュレーションを書いています。N<40 の {1,2,...,N} に一様に分散された整数を生成するために、多くのランダム ビットが必要になります。C 関数を使用する際の問題は、標準的な手法randを使用すると、完全に適切なビットが大量に無駄になることです。rand % N整数を生成するためのより良い方法は何ですか?

暗号的に安全な乱数は必要ありませんが、乱数によって結果が歪められることは望ましくありません。また、random.org からビットのバッチをダウンロードすることを解決策とは考えていません。

4

3 に答える 3

2

rand % N動作しません; RAND_MAX + 1の倍数でない限り、結果が歪められますN

正しいアプローチは、の最大の倍数を計算し、その値よりN小さくRAND_MAXなるまで乱数を生成することです。その場合にのみ、モジュロ演算を実行する必要があります。これにより、最悪の場合の拒否率は50%になります。

于 2012-05-21T18:51:27.610 に答える
1

oliの答えに加えて:

ビットがどうしても気になる場合は、ビットのキューを手動で管理し、次の数値に必要な数だけ取得することができます (つまり、upper(log2(n)))。

ただし、ジェネレーターが十分に優れていることを確認する必要があります。単純な線形合同(sp?)ジェネレーターは、下位​​ビットよりも上位ビットの方が優れているため(コメントを参照)、現在のモジュラー除算アプローチはそこでより理にかなっています。

数値レシピには、これらすべてに関する非常に優れたセクションがあり、非常に読みやすいです(ビットの保存については言及していませんが、一般的な参照として)。

必要かどうかわからない場合は更新してください。今のところ、これについて心配する必要はありません(特定のコンテキストを理解している人からより良いアドバイスがない限り).

于 2012-05-21T18:57:01.743 に答える
0

base40 で表現randし、数字を数字として受け取ります。不完全な数字はすべて削除します。つまり、最初の数字が [0..39] の範囲に収まらない場合は最初の数字を削除し、最初の数字が可能な限り高い値を取る場合は乱数全体を削除します (たとえば、RAND_MAX が base40 の場合は21 23 05 06、基数 40 の最上位桁を持つすべての数字を削除します 21)。

于 2012-05-21T19:02:06.420 に答える