나는 최근에 C ++ 11에서 난수를 생성하는 새로운 방법을 발견했지만 그것에 대해 읽은 논문 을 소화 할 수 없었 습니다 ( 엔진 , 분포 와 같은 수학 용어 , “모든 정수가 똑같이 생성 될 가능성이있는 곳 “).
누구든지 설명해 주시겠습니까
- 그들은 무엇인가?
- 무슨 뜻입니까?
- 생성하는 방법?
- 어떻게 작동합니까?
- 기타
난수 생성에 대한 하나의 FAQ에서 모든 것을 호출 할 수 있습니다.
답변
질문은 완전한 답변을하기에는 너무 광범위하지만 몇 가지 흥미로운 점을 선택하겠습니다.
“동일한 가능성이있는”이유
동일한 확률로 숫자 0, 1, …, 10을 생성하는 간단한 난수 생성기가 있다고 가정합니다 (이를 고전적인 것으로 생각하십시오 rand()
). 이제 각각 동일한 확률을 가진 0, 1, 2 범위의 난수를 원합니다. 무릎을 꿇는 반응은 rand() % 3
. 그러나 잠깐, 나머지 0과 1이 나머지 2보다 더 자주 발생하므로 이것은 올바르지 않습니다!
이것이 우리가 예에서 와 같이 균일 한 임의 정수의 소스를 가져와 원하는 분포로 바꾸는 적절한 분포 가 필요한 이유 Uniform[0,2]
입니다. 이것을 좋은 도서관에 맡기는 것이 가장 좋습니다!
엔진
따라서 모든 무작위성의 중심에는 특정 간격에 걸쳐 균일하게 분포하고 이상적으로는 매우 긴 기간을 갖는 일련의 숫자를 생성하는 우수한 의사 난수 생성기가 있습니다. 의 표준 구현은 rand()
종종 최고가 아니므로 선택하는 것이 좋습니다. Linear-congruential과 Mersenne twister는 두 가지 좋은 선택입니다 (LG는 실제로에서도 자주 사용됩니다 rand()
). 다시 말하지만, 라이브러리가 처리하도록하는 것이 좋습니다.
작동 원리
쉬움 : 먼저 엔진을 설치하고 시드하십시오. 시드는 “무작위”숫자의 전체 시퀀스를 완전히 결정하므로 a /dev/urandom
) 매번 다른 번호 (예 :에서 가져옴)를 사용 하고 b) 무작위 선택 시퀀스를 다시 생성하려는 경우 시드를 저장합니다.
#include <random>
typedef std::mt19937 MyRNG; // the Mersenne Twister with a popular choice of parameters
uint32_t seed_val; // populate somehow
MyRNG rng; // e.g. keep one global instance (per thread)
void initialize()
{
rng.seed(seed_val);
}
이제 배포판을 만들 수 있습니다.
std::uniform_int_distribution<uint32_t> uint_dist; // by default range [0, MAX]
std::uniform_int_distribution<uint32_t> uint_dist10(0,10); // range [0,10]
std::normal_distribution<double> normal_dist(mean, stddeviation); // N(mean, stddeviation)
… 엔진을 사용하여 난수를 만드세요!
while (true)
{
std::cout << uint_dist(rng) << " "
<< uint_dist10(rng) << " "
<< normal_dist(rng) << std::endl;
}
동시성
<random>
기존 방식 보다 선호하는 또 하나의 중요한 이유 rand()
는 난수 생성 스레드를 안전하게 만드는 방법이 이제 매우 명확하고 분명하다는 것입니다. 스레드 로컬 시드에 시드 된 자체 스레드 로컬 엔진을 각 스레드에 제공하거나 액세스를 동기화합니다. 엔진 개체에.
기타
답변
난수 생성기는 숫자가 주어지면 새로운 숫자를 제공하는 방정식입니다. 일반적으로 첫 번째 숫자를 제공하거나 시스템 시간과 같은 항목에서 가져온 숫자를 제공합니다.
새 번호를 요청할 때마다 이전 번호를 사용하여 방정식을 실행합니다.
난수 생성기는 다른 숫자보다 동일한 숫자를 더 자주 생성하는 경향이있는 경우 그다지 좋은 것으로 간주되지 않습니다. 즉, 1과 5 사이의 임의의 숫자를 원하고 다음과 같은 숫자 분포가있는 경우 :
- 1 : 1 %
- 2 : 80 %
- 3 : 5 %
- 4 : 5 %
- 5 : 9 %
2는 다른 숫자보다 더 자주 생성되므로 다른 숫자보다 생성 될 가능성이 높습니다. 모든 숫자가 똑같다면 매번 각 숫자를 얻을 확률이 20 %입니다. 달리 말하면 위의 분포는 2가 선호되기 때문에 매우 고르지 않습니다. 모두 20 %의 분포는 균등합니다.
일반적으로 진정한 난수를 원한다면 난수 생성기보다는 날씨 또는 다른 자연 소스와 같은 것에서 데이터를 가져옵니다.