일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 클라우드
- CUDA
- 양자역학의공준
- C++
- POD
- sycl
- quantum_computing
- 반도체
- HA
- dnn
- nvidia
- flash_memory
- 딥러닝
- jhDNN
- 쿠버네티스
- Qubit
- convolution
- DRAM
- stl
- cloud
- kubernetes
- jhVM
- GPU
- CuDNN
- Semiconductor
- FPGA
- deep_learning
- SpMM
- 반도체기초
- Compression
- 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 |