C++ 난수 생성

2023. 1. 16. 16:41개인공부/C++

C 스타일의 난수 생성의 문제점

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main() {
  srand(time(NULL));
 
  for (int i = 0; i < 5; i++) {
    printf("난수 : %d \n", rand() % 100);
  }
  return 0;
}
cs

c에서는 srand(time(NULL)) 을 이용해서 난수를 생성했지만 이 수열들은 난수처럼 보이지만 실제로는 무작위로 생성된 것이 아닌 수열을 만들어 낸다. 위의 코드들은 시드값이 너무 천천히 변하며 0부터 99까지 균등하게 난수를 생성하지 않는다.

그리고 rand() 함수는 선형 합동 생성기라는 알고리즘을 바탕으로 구현되어 있기때문에 난수열들의 상관 관계가 높아서 일부 시물레이션에 사용하기에 적합하지 않다.           

-> C++에서는 C의 srand 와 rand 는 갖다 버리자!

 

C++ 난수 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <random>
 
int main() {
  // 시드값을 얻기 위한 random_device 생성.
  std::random_device rd;
 
  // random_device 를 통해 난수 생성 엔진을 초기화 한다.
  std::mt19937 gen(rd());
 
  // 0 부터 99 까지 균등하게 나타나는 난수열을 생성하기 위해 균등 분포 정의.
  std::uniform_int_distribution<int> dis(0, 99);
 
  for (int i = 0; i < 5; i++) {
    std::cout << "난수 : " << dis(gen) << std::endl;
  }
}
cs

C++ 에서는 random_device을 이영해서 양질의 시드값을 제공받는다. 다만 진짜 난수의 경우 컴퓨터가 주변의 환경과 무작위적으로 상호작용하면서 만들어지는 것이기 때문에 의사 난수보다 난수를 생성하는 속도가 매우 느리다. 따라서 시드값처럼 난수 엔진을 초기화하는 데 사용하고, 그 이후의 난수열은 난수 엔진으로 생성하는 것이 적합하다.

random_device를 통해 난수 생성 엔진을 초기화한다. std:: mt19937은 C++ <random> 라이브러리에서 제공하는 난수 생성 엔진 중 하나로, 메르센 트위스터라는 알고리즘을 사용한다. mt19937를 생성한 이후에 난수를 생성하는 작업을 매우 빠르다.

이후에는 난수 생성 엔진을 만들었으면 C++의 경우 어디에서 수들을 뽑아낼지 알려주는 분포를 정의해야 합니다. 0부터 99까지 균등한 확률로 정수를 뽑아내고 싶다면 균등 분포 객체를 정의해야 한다. 

'개인공부 > C++' 카테고리의 다른 글

new 이중 배열 선언  (0) 2023.03.06
C++ Array 배열 초기화 방법  (0) 2023.01.29
union & bit field 로 float 자료형 구현  (0) 2022.12.30
상속  (0) 2022.12.16
tree erase 구현  (0) 2022.12.15