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::mt19937touint32_ton x64, eventually this should be fixed and you can sayMyRNG::result_type seed_valand 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 |