블로그는 나의 힘!
[ Programing ]/Algorithm2019. 11. 21. 15:28

https://blog.naver.com/devmachine/221240867011

 

[C++] 한줄 완성! 쉽고 직관적인 mt19937 난수 생성기 (Random 클래스)

C++11 기본 난수 엔진 mt19937 예전에 mt19937 난수 엔진을 소개하는 포스팅을 올린 적이 있습니다(지난 ...

blog.naver.com

 

mt19937 난수 생성기. ( C++ 11 이상 버전 )
 

/**************************************************************/
/// @author : Q
/// @date : 20191018
/// @brief : mt19937 Type Random Generator
/// @note : mt19937 랜덤 선언 단순화
/// @remark :
//     mt19937_Random<int> _rand(0, 1000);
//     int num = _rand();
//     (OR)
//     int seed = 1;
//     mt19937_Random<int> _rand(-100, 1000, seed);
//     int num = _rand();
/**************************************************************/

template <typename Type>
class mt19937_Random
{
public:
     static_assert(std::is_arithmetic::value, "Invalid template argument data");
 
     // 정수 타입이며 byte size가 2보다 작다면 short
     // 1byte 타입 정의 일때 2byte short로 정의.
     // uniform_XXX_distribution -> char(1byte) 지원 안함.  1 = 1 - 1 + 1^2 랜덤 불가.
     // [ 공식: P(i|a,b) = 1 / (b - a) + 1 ]
     using IntegerType = typename std::conditional<(std::is_integral::value<Type> && sizeof(Type) < 2), 
                             short, Type>::type;
 
     // 타입이 정수면 uniform_int_distribution, 실수면 uniform_real_distribution
     // uniform_XXX_distribution : 랜덤 시작~끝의 균등한 분포도. (Random 값 담기 위한)
     using Distribution = typename std::conditional<std::is_floating_point<Type>::value,
                             std::uniform_real_distribution<Type>, std::uniform_int_distribution<IntegerType> >::type;
 
     // size(Type) 4 초과라면 std::mt19937_64 || size(Type) 4 이하라면 std::mt19937
     using Engine = typename std::conditional<(std::is_integral<Type>::value && sizeof(Type) > 4),
                       std::mt19937_64, std::mt19937>::type;
 
     // 생성자의 매개변수 미 설정시 정의 된 template 타입의 사이즈로 정의. (EX: mt19937_Random _rand;)
     // numeric_limits::min : 인자값이 없다면 타입 정의의 최소값으로 설정. (EX: int 라면 -2,147,483,648)
     // numeric_limits::max : 인자값이 없다면 타입 정의의 최대값으로 설정. (EX: int 라면 2,147,483,647)
     mt19937_Random( Type min = (std::numeric_limits<Type>::min)(), Type max = (std::numeric_limits<Type>::max)(),
                          typename Engine::result_type seed = std::random_device()() )
     : _engine(seed), _distribution((std::min)(min, max), (std::max)(min, max))
     {}
 
     Type operator()() { return static_cast<Type>(_distribution(_engine)); }
private:
     Engine _engine;
     Distribution _distribution;
};
 
int main()
{
     mt19937_Random<int> _rand1(0, 10000);
     int value1 = _rand1();

     int seed = 1;
     mt19937_Random<int> _rand2(-100, 10000, seed);
     int value2 = _rand2();
 
     mt19937_Random<char> _rand3;
     char value3 = _rand3();
 
     return 0;
}



 

Posted by Mister_Q