#include <iostream>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
for (int i = 0; i < 5; i++) {
std::cout << "난수 : " << rand() % 100 << '\n';
}
return 0;
}
0~99까지의 난수를 생성하는 코드
엄밀히 말하자면 마치 난수처럼 보이는 의사 난수를 생성하는 코드임
무작위로 정해진 첫 번째 수를 시드(seed)라고 부르는데, C의 경우 srand를 통해 seed를 설정할 수 있음
여기서는 time(NULL)을 통해 프로그램을 실행했던 초를 시드값으로 지정했음
그렇게 되면 rand()는 호출할 때마다 시드값을 기반으로 무작위처럼 보이는 수열을 생성하게 됨
위와 같은 방식의 문제는
#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;
}
}
std::random_device rd;
수학적 알고리즘을 통해 생성되는 가짜 난수가 아닌 컴퓨터가 실행하면서 마주치는 무작위적인 요소들(ex. 장치드라이버들의 noise)을 기반으로한 진정한 난수 제공
다만, 컴퓨터가 주변의 환경과 무작위적으로 상호작용하면서 만들어지는 것이기 때문에 의사 난수보다 난수를 생성하는 속도가 매우 느림
따라서, 시드값처럼 난수 엔진을 초기화하는데 사용하고, 그 이후의 난수열은 난수 엔진으로 생성하는 것이 적합함
💡 <random> 라이브러리의 minstd_rand
: rand와 같이 선형 합동 알고리즘을 사용한 엔진
std::mt19937 gen(rd());
생성한 random_device 객체를 이용해서 난수 생성 엔진 객체를 정의
만약 random_device대신에 그냥 원하는 값을 시드값으로 넣어주고 싶다면
std::mt19937 gen(1234);
이런식으로 값을 넣어주면 됨
std::uniform_int_distribution<int> dis(0,99);
균등한 확률로 정수를 뽑아내고 싶다면 위와 같이 균등 분포 객체를 정의해야 함
위와 같이 생성자에 원하는 범위를 써넣으면 됨
for (int i = 0; i < 5; i++) {
std::cout << "난수 : " << dis(gen) << std::endl;
}
마지막으로 균등 분포에 사용할 난수 엔진을 전달함으로써 균등 분포에서 무작위로 샘플을 뽑아낼 수 있음
💡 normal_distribution
: <random> 라이브러리에 있는 여러가지 분포들 중 하나인 정규 분포std::normal_distribution<double> dist(0, 1);위의 코드는 평균 0이고 표준 편차가 1인 정규 분포를 정의한 것