| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
- 딥러닝
 - SpMM
 - Compression
 - 반도체기초
 - HA
 - jhDNN
 - 반도체
 - GPU
 - dnn
 - FPGA
 - flash_memory
 - CUDA
 - deep_learning
 - CuDNN
 - kubernetes
 - Semiconductor
 - C++
 - 클라우드
 - POD
 - cloud
 - 쿠버네티스
 - DRAM
 - jhVM
 - Qubit
 - quantum_computing
 - convolution
 - stl
 - 양자역학의공준
 - sycl
 - nvidia
 
- Today
 
- Total
 
Computing
[C++] 진짜 랜덤 숫자 생성하기 (std::random_device) 본문
기존 C-style 랜덤 숫자 생성 방법 및 한계
밑의 코드 예시는 기존 C-style code에서 랜덤 숫자 (정확히는 랜덤한 것처럼 느껴지는 pseudo-random 숫자를 생성) 를 생성하는 코드이다. std::rand()함수[1]는 Seed 숫자를 이용해 어떤 숫자를 생성하는데, std::srand() 함수를 이용하면 std::rand()함수가 사용하는 Seed 숫자를 설정할 수 있다. 밑의 코드에서는 std::srand() 함수를 이용해 Seed를 현재 시간으로 설정하였다.
 
#include <ctime>
#include <cstdlib>
...
    std::srand(time(NULL)); 랜덤 생성 시의 Seed 설정. Seed를 현재 시간으로 설정한다.
    for (int i=0; i<10; i++) {
    	// int std::rand() 함수는 의사 난수 (pseudo-random, 랜덤한 것같은 숫자) 숫자를 생성함
        // int std::rand() 가 생성하는 의사 난수는 0부터 RAND_MAX(32767) 중 하나이다.
        int random_value = std::rand() % 100; 
    }
... // 계속 
문제는 C-style std::rand() 함수가 생성하는 랜덤 숫자는 그 퀄리티에 문제가 있다고 한다[1].
1. 기본적으로 랜덤하게 생성되는 숫자의 크기가 최대 32767밖에 안된다.
2. 생성되는 숫자들의 분포가 균일하지 않는다고 한다.
3. 랜덤한 숫자를 생성하는 알고리즘이 존재하기에 std::rand() 함수가 생성하는 의사 난수는 결정적(deterministic)이고 std::srand()에서 설정한 Seed값만 알면 어떤 랜덤한 숫자가 생성되는 지를 알 수 있다.
구체적인 단점은 다음과 같다[2].
 
 
 
std::random_device의 도입과 예시
다양한 시뮬레이션 환경을 개발할 때, 균일한 분포를 가지는 진정으로 랜덤한 숫자에 대한 필요성은 항상 존재할 것이다. Modern C++ (Since C++11) 부터는 std::rand() 함수를 대체하기 위해 std::random_device class[3]가 도입되었다. std::random_device는 균일한 분포(uniformly-distributed)를 가진 비결정적(non-deterministic)인 int 숫자를 생성하는 클래스이다.
 
컴퓨터가 비결정적인 숫자를 생성할 수 있다는 것이 놀라운데, 구현에서 실제 물리 디바이스 (hardware) 와 연관된 어떠한 랜덤한 특징을 이용해 비결정적인 진짜 랜덤한 숫자를 생성해낸다고 한다.
std::random_device를 이용한 랜덤 숫자 생성 예시는 다음과 같다.
 
#include <iostream>
#include <random>
int main(void) {
    std::random_device rd;
    std::cout << "Min Value : " << rd.min() << std::endl;
    std::cout << "Max Value : " << rd.max() << std::endl;
    for (int i=0; i<3; i++) {
        std::cout << " - Generated Random Value : " << rd() << std::endl;
    }
}
////////////////////////
// 결과
// Min Value : 0
// Max Value : 4294967295
//  - Generated Random Value : 3499211612
//  - Generated Random Value : 581869302
//  - Generated Random Value : 389034673 
std::random_device는 Class이기에 선언을 통해 객체 rd를 초기화한다. rd.min() 함수와 rd.max() 함수를 통해 std::random_device가 생성하는 최소, 최대 값을 확인할 수 있는데, 최소 값은 0u와 같고, 최대 값은 std::numeric_limits<unsigned int>::max() 와 같다.
 
opeator()를 이용하면 드디어 랜덤 숫자를 생성할 수 있다. operator() 실행 시, [min(), max()] 범위에서 균일한 분포를 가지도록 랜덤한 숫자들을 출력한다.
 
 
 
Reference
[1] https://en.cppreference.com/w/cpp/numeric/random/rand
[2] https://stackoverflow.com/questions/53040940/why-is-the-new-random-library-better-than-stdrand
[3] https://en.cppreference.com/w/cpp/numeric/random/random_device
'Programming > C++' 카테고리의 다른 글
| [C++ STL] std::set을 통한 중복 제거 (Duplicate 판단 기준) (0) | 2024.05.09 | 
|---|---|
| [문법] 대입 연산자의 반환 (Return 값) (0) | 2023.12.17 | 
| [c++] 싱글톤 디자인 패턴 최적 구현 (Singleton design pattern) (1) | 2023.11.26 | 
| [STL] Set, Map Custom Sort 구현 방법 (Red-black tree) (4) | 2023.10.18 | 
| 스마트 포인터 정리 (Smart Pointer, unique_ptr, shared_ptr) (0) | 2023.08.19 |