랜덤 숫자 생성 (Random Number Generation)
개요
C++에서의 랜덤 숫자 생성은 <random>
헤더를 통해 제공되는 다양한 유틸리티를 사용하여 구현할 수 있습니다. C++11부터 도입된 이 라이브러리는 예측 가능한 의사 난수 생성기와 다양한 분포를 제공합니다.
C++ 버전별 주요 키워드 도입 시기
- C++11:
<random>
헤더,std::random_device
,std::mt19937
,std::uniform_int_distribution
등 도입 - C++14:
std::make_unique
를 사용한 랜덤 엔진 생성이 용이해짐 - C++17:
std::sample
알고리즘 추가 - C++20:
std::uniform_random_bit_generator
개념(concept) 도입
내용 설명
C++에서 랜덤 숫자 생성을 위해서는 다음과 같은 컴포넌트들이 사용됩니다:
- 시드 생성기 (Seed Generator):
std::random_device
: 하드웨어 기반의 난수 생성기로, 시드 생성에 주로 사용됩니다.- 시드가 예측 불가능해야 할 경우에만
std::random_device
를 사용하고, 그렇지 않다면 상수 값을 사용할 수도 있습니다.
- 의사 난수 엔진 (Pseudo-random Number Engine):
std::mt19937
: 메르센 트위스터 알고리즘을 구현한 32비트 의사 난수 생성기std::mt19937_64
: 64비트 버전의 메르센 트위스터std::minstd_rand
: 더 간단하고 빠른 선형 합동 생성기
- 분포 (Distribution):
std::uniform_int_distribution
: 균일한 정수 분포std::uniform_real_distribution
: 균일한 실수 분포std::normal_distribution
: 정규 분포std::bernoulli_distribution
: 베르누이 분포- 기타 다양한 통계적 분포 제공
예제 코드
#include <cstdint>
#include <iostream>
#include <random>
#include <vector>
namespace
{
constexpr auto NUM_ELEMENTS = size_t{1'000'000U};
};
int main()
{
// 1. 벡터 생성 및 0으로 초기화
auto my_vector = std::vector<std::int32_t>(NUM_ELEMENTS, 0U);
// 2. 난수 생성기 초기화
auto seed = std::random_device{}; // 시드 생성기
auto gen = std::mt19937{seed()}; // 메르센 트위스터 엔진
// 3. 분포 설정 (-10에서 10 사이의 균일한 정수 분포)
auto dist = std::uniform_int_distribution<std::int32_t>{-10, 10};
// 4. 벡터에 난수 채우기
for (auto &val : my_vector)
{
val = dist(gen); // 분포를 사용하여 난수 생성
}
// 5. 처음 10개 요소 출력
for (std::size_t i = 0; i < 10; ++i)
{
std::cout << my_vector[i] << '\n';
}
return 0;
}
실행 결과
프로그램을 실행할 때마다 다른 난수들이 생성됩니다. 예시 출력:
3
-5
7
2
-8
4
1
-2
9
0
활용팁
- 성능:
std::random_device
는 암호학적으로 안전하지만 상대적으로 느릴 수 있습니다. 성능이 중요한 경우, 프로그램 시작 시 한 번만 시드를 생성하고 재사용하세요. - 디버깅: 재현 가능한 결과가 필요하다면, 시드를 고정값으로 설정할 수 있습니다.
// 디버깅용 고정 시드 std::mt19937 gen(42); // 고정된 시드 값
- 스레드 안전: 난수 생성기는 스레드 안전하지 않습니다. 각 스레드마다 별도의 생성기 인스턴스를 사용하거나, 뮤텍스로 보호해야 합니다.
- 분포 선택: 필요한 통계적 특성에 맞는 적절한 분포를 선택하세요. 예를 들어, 정규 분포가 필요한 경우
std::normal_distribution
을 사용할 수 있습니다. - C++17의 std::sample: 컨테이너에서 무작위 표본을 추출할 때 유용합니다.
std::vector<int> source = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; std::vector<int> out; std::sample(source.begin(), source.end(), std::back_inserter(out), 3, std::mt19937{std::random_device{}()});
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : std::chrono 날짜 및 시간대 (11, 14, 17, 20) (0) | 2025.09.06 |
---|---|
Modern C++ : std::chrono 시간 측정 (11, 14, 17, 20) (0) | 2025.09.05 |
Modern C++ : std::filesystem (0) | 2025.09.03 |
Modern C++ : std::ostream & std::istream (98, 11, 17, 20) (0) | 2025.09.02 |
Modern C++ : std::string_view (17, 20) (1) | 2025.09.01 |
Modern C++ : Small String Optimization (SSO) (3) | 2025.08.31 |
Modern C++ : std::string (98, 11, 17, 20) (3) | 2025.08.30 |
Modern C++ : Custom Iterator Utilities (98, 11, 17, 20) (0) | 2025.08.29 |