페이지

Include Lists

2017년 1월 19일 목요일

C++11 부터 적용된 Random 함수


 What
   - 난수 추출 함수 (Pseudorandom number generator)
   - C++ 11부터 표준으로 등록 (Pseudorandom number generator)
   - 메르센 트위스터 엔진 사용 (Pseudorandom number generator)

   ※ 메르센 트위스터 : 1997년에 마츠모토 마코토와 니시무라 다쿠지가 개발한 유사난수 생성기. 난수의 반복주기가 메르센 소수인데에서 유래되었다. (Pseudorandom number generator)
   ※ 메르센 소수 : 2의 거듭제곱에서 - 1을 한 수.

 Why
   - rand보다 명확한 난수를 추출해내기 위해 사용한다.

 Usage
   - random.h


C++11으로 들어가면서, 
메르센 트위스터를 이용한 난수 생성 헤더인 <random> 헤더가 추가되었다.
random 헤더를 이용하여 난수를 추출하는 단계는 크게 3단계로 나눠진다.

1. 시드 설정
2. 범위 설정
3. 난수 추출

첫번째, 시드설정은 시드값이 아닌 하드웨어의 리소스 ( 시간마우스 움직임등 ) 를 사용한다는 특징을 가지고 있다.
이 방식은 기존의 rand 함수보다 좀 더 난수다운 난수를 생성하기 위해 사용되었다.

내부에는 std::random_device 라는 클래스로 정의되어 있다.
std::random_device 형 객체를 만들면, 내부에서 하드웨어의 리소스로 랜덤한 숫자를 생성한다.

이렇게 생성된 객체를 내부에 선언되어 있는 여러가지 엔진에 전달한다.
기본적인 랜덤 엔진 (default_random_engine) 으로 정의되어 있는 것은 mt19937 ( 메르센 트위스터 ) 엔진이다.


위의 과정을 거쳐 시드설정이 끝났다면, 난수의 생성 형식과 타입을 결정해야 한다.

만약
실수 난수가 필요하다면 std::uniform_real_distribution,
정수 난수가 필요하다면 std::uniform_int_distribution,
정규 분포를 갖는 랜덤값이 필요하다면 std::normal_distribution 등, 
여러가지 난수 분포들이 존재한다.
이러한 난수 분포를 통해 생성 형식을 결정한다.


이렇게 난수 분포까지 끝났다면, 난수를 생성할 수 있다.

이를 코드로 옮겨 보았다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <random>
int main
{
    //< 1단계. 시드 설정
    std::random_device rn;
    std::mt19937_64 rnd( rn() );
 
    //< 2단계. 분포 설정 ( 정수 )
    std::uniform_int_distribution<int> range(min, max);
 
    //< 3단계. 값 추출
    int val = range( rnd );
}
cs

주의해야 할 점은, 범위를 설정할 때, 0, 10으로 설정했다면, rand와 달리 10도 추출될 수 있다는 점을 주의해야 한다.



출처: http://gabble-workers.tistory.com/7 [게임공작소]