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 forstd::mt19937
touint32_t
on x64, eventually this should be fixed and you can sayMyRNG::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.
'Programing' 카테고리의 다른 글
ASP.NET MVC 응용 프로그램에서보기 별 javascript 파일을 어디에 배치합니까? (0) | 2020.09.04 |
---|---|
fmap이있을 때 Haskell에서지도의 요점은 무엇입니까? (0) | 2020.09.04 |
구분 기호가있는 String.Split (.net)의 반대 (0) | 2020.09.04 |
Django 1.7 및 데이터 마이그레이션으로 초기 데이터로드 (0) | 2020.09.04 |
Array.prototype.includes 대 Array.prototype.indexOf (0) | 2020.09.04 |