Programing

C ++ 11에서 난수 생성 : 생성 방법, 작동 원리

crosscheck 2020. 9. 4. 06:55
반응형

C ++ 11에서 난수 생성 : 생성 방법, 작동 원리 [닫은]


나는 최근에 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()는 난수 생성 스레드를 안전하게 만드는 방법이 이제 매우 명확하고 분명하다는 것입니다. 스레드 로컬 시드에 시드 된 자체 스레드 로컬 엔진을 각 스레드에 제공하거나 액세스를 동기화합니다. 엔진 개체에.

기타

  • codeguru에서 무작위로 TR1에 대한 흥미로운 기사 .
  • Wikipedia 에는 좋은 요약이 있습니다 (감사합니다, @Justin).
  • In principle, each engine should typedef a result_type, which is the correct integral type to use for the seed. I think I had a buggy implementation once which forced me to force the seed for std::mt19937 to uint32_t on x64, eventually this should be fixed and you can say MyRNG::result_type seed_val and thus make the engine very easily replaceable.

A random number generator is a equation that, given a number, will give you a new number. Typically you either provide the first number or its pulled from something like the system time.

Each time you ask for a new number it uses the previous number to execute the equation.

A random number generator is not considered very good if it has a tendency to produce the same number more often than other numbers. i.e. if you wanted a random number between one and 5 and you had this distribution of numbers:

  • 1: 1%
  • 2: 80%
  • 3: 5%
  • 4: 5%
  • 5: 9%

2 is generated FAR more often than any other number, so it is more likely to be produced than other numbers. If all numbers were equally like you would have a 20% chance of getting each number every time. To say it another way, the above distribution is very uneven because 2 is favored. A distribution with all 20%'s would be even.

Typically, if you want a true random number you would pull data from something like weather or some other natural source rather than a random number generator.

참고URL : https://stackoverflow.com/questions/7114043/random-number-generation-in-c11-how-to-generate-how-does-it-work

반응형