programing

왜 C++ rand()는 같은 크기의 숫자만 생성하는 것 같습니까?

prostudy 2022. 7. 5. 22:12
반응형

왜 C++ rand()는 같은 크기의 숫자만 생성하는 것 같습니까?

에서 C/C++로 하였습니다.rand: 능능능 function function function : 능능 function function function :

다른 순서, 즉 다른 로그 값(기본값 2)을 가진 일련의 난수를 생성하려고 합니다.그러나 생성되는 모든 숫자는 2^25와 2^30 사이에서만 변동하는 동일한 순서로 보입니다.

그 이유는?rand()Unix 시간 " " " " " " " " " " " " " " " " " " ?가가 뭘뭘 ?? ?? ???를 뿌리고 있다rand()main().

옅은 녹색은 0과25 2 사이의 영역이고 진한 녹색은 2와30 2 사이의25 영역입니다.진드기는 2의 거듭제곱이다.

distribution

1과30 2 사이에 있는 숫자는 2와30 2 사이에25 없는 3%뿐입니다.이것은 지극히 정상적인 것처럼 들립니다.

왜냐하면25 2 / 230-5 = 2 = 1/32 = 0.03125 = 3.125%

좀 더 정확하게 해야 합니다. 다른 2진수 로그 값을 원하지만 이 값에는 어떤 분포를 원합니까?표준 rand() 함수는 균일한 분포를 생성하므로 원하는 분포와 관련된 분위수 함수를 사용하여 이 출력을 변환해야 합니다.

저희가 수 있습니다.quantile필요한 기능을 제공합니다.

그냥 ' 크다', '보다 크다', '보다 크다', '보다 크다'를 시도해 보는 것은 요?pow(2, rand())아니면 해롤드가 제안한 대로 직접 rand()로 주문을 선택할 수도 있습니다.

@C4stor의 지적은 훌륭했다.단, 보다 일반적인 경우로서 인간(베이스 10): 1~10^n 범위의 경우, 수치의 90%가 10^(n-1)~10^n이므로 수치의 99%는 10^(n-2)~10^n이다.원하는 만큼 소수점을 계속 추가하세요.

재미있는 수학이군, n에 대해 계속 이렇게 하면, 1에서 10^n, 99.999를 볼 수 있어.이 방법에서는 % = 100%의 수치가 10^0 ~ 10^n이다.

코드에 대해서는 0에서 10^n까지의 임의의 차수의 랜덤한 숫자를 원하는 경우 다음을 수행할 수 있습니다.

  1. 0에서 n 사이의 작은 난수 생성

  2. n 의 범위를 알고 있는 경우는, 순서 10 ^k 의 큰 난수를 생성합니다.여기서 k > max { n } 。

  3. 이 큰 난수의 n자리 숫자를 얻으려면 긴 난수를 잘라내십시오.

기본(및 올바른) 답변은 이미 제공되었고 받아들여졌습니다.0과 9 사이의 10개의 숫자, 10과 99 사이의 90개의 숫자, 100과 999 사이의 900개의 숫자 등입니다.

대략적인 로그 분포를 사용하여 분포를 계산적으로 효율적으로 얻기 위해 랜덤 수를 난수만큼 오른쪽 이동하려고 합니다.

s = rand() & 31; // a random number between 0 and 31 inclusive, assuming RAND_MAX = 2^32-1
r = rand() >> s; // right shift

완벽하지는 않지만 컴퓨팅보다 훨씬 빠릅니다.pow(2, rand()*scalefactor)계수 2 내의 숫자(128~255의 경우 균등, 256~1023의 경우 밀도의 절반 등)에 대해서는 균일한 분포를 나타낸다는 점에서 「점프」가 됩니다.

다음은 숫자 0 ~ 31의 주파수 히스토그램(1M 샘플)입니다.

enter image description here

0과 2^29 사이와 2^29와 2^30 사이는 정확히 같은 수의 숫자가 있습니다.

이 문제를 바라보는 또 다른 방법으로는 생성되는 난수의 바이너리 표현을 고려해 주십시오.가장 높은 비트가 1일 확률은 1/2이므로 절반의 경우 29의 순서를 얻을 수 있습니다.필요한 것은 2^25보다 작은 수치를 확인하는 것이지만, 이는 5비트의 최고값이 모두 0임을 의미합니다.이것은 1/32의 낮은 확률로 발생합니다.장시간 실행해도 15 미만의 순서는 전혀 표시되지 않을 가능성이 있습니다(6회 연속 롤링과 비슷합니다).

자, 씨앗에 대한 질문의 한 부분입니다.아니요, 시드는 숫자가 생성되는 범위를 결정할 수 없습니다.첫 번째 초기 요소만 결정합니다.rand()는 범위 내에서 가능한 모든 숫자의 시퀀스라고 생각하십시오(미리 결정된 순열).시드에 따라 수열에서 숫자를 그리기 시작하는 위치가 결정됩니다.따라서 (의사적인) 랜덤성을 원하는 경우 현재 시간을 사용하여 시퀀스를 초기화합니다.시작하는 위치가 균일하게 분포되어 있지 않다는 것은 중요하지 않습니다.단, 중요한 것은 같은 위치에서 시작하지 않는다는 것입니다.

사용하다pow(2,rand())원하는 크기의 순서대로 정답이 나옵니다!!

wget을 사용할 수 있는 온라인 서비스의 난수를 사용하고 싶은 경우, random.org 등의 서비스를 사용하여 난수를 생성할 수도 있습니다.wget을 사용하여 다운로드한 파일에서 번호를 읽어낼 수도 있습니다.

wget -q https://www.random.org/integers/?num=100&min=1&max=100&col=5&base=10&format=html&rnd=new -O new.txt

http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html

언급URL : https://stackoverflow.com/questions/17209882/why-does-c-rand-seem-to-generate-only-numbers-of-the-same-order-of-magnitude

반응형