0

実際、私はいくつかの織り交ぜる質問があります。(重要な場合はC#を使用します。)

初め。0からUInt32.MaxまでのUInt32範囲の乱数を生成するprngがあります。できるだけ均一性を保ちたいです。[a、b]、(a、b)の二重範囲([0,1]、[0,1)、(0,1)、[-2,4]、(-など)を取得するための主なアイデアは何ですか10,10))?

次のことが気になります。4 294 967296prngの結果があります。[0,1] double範囲の数値よりも小さい— 2^53。そこで、2桁から4 294 967 296-ary番号を作成します。これは、[0、4294967295 * 4294967296+4294967295]でランダムで均一です。この最大値は1の2^53より大きいため、1つ取得した場合は破棄し、再計算してmod 2 ^ 53を使用し、たとえば[0,1]で背番号を取得します。ここでは、最大値をdoubleとして表す必要があります(Int64タイプがないと仮定します)—これには欠点がありますか?

ここで、[0,1)を取得したい場合、結果の数は(2 ^ 53)-1であると考えます。最後の結果に1 /(2 ^ 53)を追加すると、(0,1]にランダムなdoubleが生成されます。 。(0,1)を取得するには、(2 ^ 53)-2つの新しい結果を検討し、0ベースの結果に1 /(2 ^ 53)を追加します。それはすべて正しいですか。

しかし、ダブルレンジ全体に近いか等しいダブルレンジを取得するにはどうすればよいですか?上記のようにn-ary数を作成しても、Double.Maxより大きくなる場合があります。いくつかのビットシフト/ビットマスクアプローチが可能でしょうか?

2番。これで、結果が[0,1)のdouble prngがあり、[Double.Min、Double.Max]の範囲を取得することは可能ですか?ダブルナンバーはいくつありますか?フルダブルレンジprngがある場合、UIntレンジを取得するための最良の方法は何ですか?「直接」マップするか、前に[0,1]にスケーリングしますか?

第3。このコードを見つけました(http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c):

 /* generates a random number on [0,1) with 53-bit resolution*/
 double genrand_res53(void) 
 { 
     unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
     return(a*67108864.0+b)*(1.0/9007199254740992.0); 
 } 

なぜaとbが5と6にシフトし、その後a * 67108864.0 + bが均一になるのですか?

ありがとうございました。

4

1 に答える 1

1

Good random number generators produce random bits at all positions. Certain classes of poor ones produce poor randomness in the lower order bits. Thus, if you need 53 bits and generate 64, you want to throw away the 11 lowest order bits--in the case of the example code you posted, 5 from one number and 6 from another. Now you have a 26 bit number and a 27 bit number; 2^26 is 67108864 and 2^53 is 9007199254740992, which should explain why those constants are used to scale those numbers into [0,1). (It's a mixed-base number: 67108864-ary for the first digit, and 134217728-ary for the second.)

(The reason 53 bits are often used is that it makes the numbers symmetric upon subtraction--otherwise, the values between 2^-53 and 2^-64 will disappear when you subtract them from 1.)

Also, you shouldn't resample when you have too many bits--just throw away surplus bits (unless you have less than one).

Anyway, the obvious method gives you [0,1). If you want (0,1] thats 1 - [0,1). If you want (0,1), sample again if you get both a=0 and b=0. If you want [0,1], note that there is a 1 in (2^53+1) chance of getting 1, and otherwise you have [0,1). You could approximate this by getting a random number in [0,1) and checking if it's zero, and picking 1 as the answer if so, or picking again from [0,1) if not. Your random number generator probably doesn't have a long enough period to be more exact than that anyway.

于 2011-03-29T13:59:36.360 に答える