2011-03-29 4 views
0

사실, 저는 여러 가지 복잡한 질문이 있습니다. (중요한 경우 C#을 사용합니다.)스케일링 Int 무작위 범위를 Double one으로 조정합니다.

먼저. UInt32 범위에서 0부터 UInt32.Max까지의 난수를 생성하는 prng가 있습니다. 가능한 한 균일 성을 유지하고 싶습니다. [0,1], [0,1], (0,1), [-2,4], (-)와 같은 [a, b], (a, b) 10,10))?

다음에 대해 우려하고 있습니다. 나는 4 294 967 296 prng 결과가있다. [0,1] 배의 범위 - 2^53에있는 숫자보다 적습니다. 그래서 나는 [0, 4294967295 * 4294967296 + 4294967295]에서 무작위이고 일정한 2 자리 숫자에서 4 294 967 296 숫자를 생성합니다. 이 최대 값은 1에서 2^53보다 큽니다. 따라서 하나를 버리고 재 계산하고, mod 2^53을 사용하고, 예를 들어, [0,1]에서 균일 한 숫자를 얻으십시오. 여기에 최대 값을 두 번 표현해야합니다 (Int64 유형이 없다고 가정). 거기에 단점이 있습니까?

결과를 얻으려면 (2^53) - 1이라고 생각합니다. 마지막 결과 1/(2^53)을 추가하면 (0,1] (0,1)을 얻으려면 (2^53) - 2 개의 새로운 결과를 고려하고 0 기반 결과에 1/(2^53)을 더하십시오. 모두 정확합니까?

위와 같이 n-ary 숫자를 구성하더라도 Double.Max보다 커질 수 있습니다. 일부 비트 시프트/비트 마스크 접근이 가능할 수 있습니다.

초. 이제 [0,1]의 결과에 대한 이중 prng이 [Double.Min, Double.Max] 범위를 얻을 수 있습니까? 얼마나 많은 이중 숫자? 전체 이중 범위 명령이있는 경우 UInt 범위를 가져 오는 가장 좋은 방법은 무엇입니까 - 직접 "직접"매핑하거나 [0,1]로 확장할까요?

셋째.

/* 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 :이 코드 (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c를) 발견 5와 6으로 바뀌었고 왜 그 후에 * 67108864.0 + b가 일정합니까?

감사합니다.

답변

1

좋은 난수 생성기는 모든 위치에서 임의 비트를 생성합니다. 불량 클래스의 특정 클래스는 하위 비트에서 불량 임의성을 생성합니다. 따라서 53 비트가 필요하고 64를 생성하는 경우 11 개의 최하위 비트를 버리려고합니다. 게시 한 예제 코드의 경우 한 숫자에서 5, 다른 숫자에서 6을 버립니다. 이제 26 비트 숫자와 27 비트 숫자가 있습니다. 2^26이 67108864이고 2^53이 9007199254740992인데 왜이 상수가 [0,1]로 그 숫자를 확장하는 데 사용되는지 설명해야합니다.

(53 비트를 자주 사용하는 이유는 빼기에 숫자가 대칭이되는 이유입니다. 그렇지 않은 경우,

또한 비트 수가 너무 많을 때 다시 샘플링하면 안됩니다. 잉여 비트를 버리십시오 (단, 가지고 있지 않은 경우 제외). 하나 이하).

어쨌든 분명한 방법은 [0,1]입니다. 원하는 경우 (0,1) thats 1 - [0,1]. 원하는 경우 (0,1), = 0과 b = 0을 모두 얻으면 다시 샘플링하십시오. [0,1]을 원할 경우, 1 (2^53 + 1)의 확률로 1을 얻고, 그렇지 않으면 [0,1]을가집니다. [0,1]에 임의의 숫자를 가져 와서 제로인지 확인하고, 대답이 1 일 경우 대답을 선택하거나 그렇지 않은 경우 [0,1]에서 다시 선택하여이를 근사시킬 수 있습니다. 귀하의 난수 생성기는 아마도 어쨌든 그보다 정확하기에는 충분히 긴 기간이 없을 것입니다.