Pseudo-random number generation
난수 라이브러리는 무작위 및 의사 무작위 숫자를 생성하는 클래스를 제공합니다. 이러한 클래스에는 다음이 포함됩니다:
- 균일 난수 비트 생성기(URBG)는 균일 분포를 가진 정수 시퀀스를 생성하는 의사 난수 생성기인 난수 엔진과 (사용 가능한 경우) 진난수 생성기를 모두 포함합니다.
- 난수 분포 (예: uniform , normal , 또는 poisson distributions )는 URBG의 출력을 다양한 통계적 분포로 변환합니다.
URBG와 분포는 함께 사용되어 난수 값을 생성하도록 설계되었습니다. 모든 난수 엔진은 특정 시드 값으로 초기화되고, 직렬화 및 역직렬화되어 반복 가능한 시뮬레이터와 함께 사용될 수 있습니다.
목차 |
균일 무작위 비트 생성기
균일 난수 비트 생성기 는 가능한 결과 범위 내의 각 값이 (이상적으로) 동일한 확률로 반환되는 부호 없는 정수 값을 반환하는 함수 객체입니다.
모든 균일 난수 비트 생성기는
UniformRandomBitGenerator
요구 사항을 충족합니다.
C++20은 또한
uniform_random_bit_generator
개념을 정의합니다.
|
헤더 파일에 정의됨
<random>
|
|
|
(C++20)
|
타입이 균일 난수 비트 생성자로 적합함을 명시
(concept) |
난수 엔진
랜덤 넘버 엔진 (일반적으로 엔진 으로 줄여씀)은 시드 데이터를 엔트로피 소스로 사용하여 의사 난수를 생성하는 균일 난수 비트 생성기입니다.
언제든지, 타입
E
의 엔진
e
는 음수가 아닌 정수
i
에 대한 상태
e
i
를 가집니다. 생성 시,
e
는 엔진 매개변수와 초기 시드(또는 시드 시퀀스)에 의해 결정되는 초기 상태
e
0
를 가집니다.
다음 속성들은 모든 엔진 유형
E
에 대해 항상 정의됩니다:
-
E의 상태 크기를E::result_type의 크기 배수로 나타낸 값(즉, ( sizeof ei) / sizeof ( E :: result_type ) ). -
e
의 상태
e
i를 후속 상태 ei+1로 전이시키는 전이 알고리즘 TA (즉, TA ( ei) == ei+1). -
e
의 상태를
E::result_type타입의 값으로 매핑하는 생성 알고리즘 GA , 그 결과는 의사 난수입니다.
의사 난수 시퀀스는 TA 와 GA 를 번갈아 호출하여 생성할 수 있습니다.
표준 라이브러리는 세 가지 다른 종류의 의사 난수 생성 알고리즘 구현을 클래스 템플릿으로 제공하므로 알고리즘을 사용자 정의할 수 있습니다. 어떤 엔진을 사용할지 선택하는 것은 여러 가지 절충점을 수반합니다:
- 선형 합동 엔진 은 비교적 빠르며 상태 저장을 위한 요구 공간이 매우 작습니다.
- 메르센 트위스터 엔진 은 더 느리고 상태 저장 요구 사항이 더 크지만, 적절한 매개변수를 사용할 경우 가장 긴 비반복 시퀀스와 가장 바람직한 스펙트럼 특성(바람직함의 정의에 따라)을 가집니다.
- 캐리 감산 엔진 은 고급 산술 명령어 세트가 없는 프로세서에서도 매우 빠르게 동작하지만, 더 큰 상태 저장 공간과 때로는 덜 바람직한 스펙트럼 특성을 가지는 단점이 있습니다.
|
(C++26부터) |
이들 난수 엔진 중 그 어느 것도
암호학적으로 안전하지
않습니다. 모든 보안 작업과 마찬가지로, 해당 목적을 위해서는 암호화 라이브러리를 사용해야 합니다 (예:
OpenSSL
RAND_bytes
).
이 템플릿들로부터 인스턴스화된 모든 타입은 RandomNumberEngine 요구 사항을 충족합니다.
|
헤더 파일에 정의됨
<random>
|
|
|
(C++11)
|
선형 합동
알고리즘을 구현함
(클래스 템플릿) |
|
(C++11)
|
메르센 트위스터
알고리즘을 구현함
(클래스 템플릿) |
|
(C++11)
|
캐리 감산(
지연 피보나치
) 알고리즘을 구현함
(클래스 템플릿) |
|
(C++26)
|
카운터 기반 병렬화 가능 생성기
(클래스 템플릿) |
난수 엔진 어댑터
랜덤 넘버 엔진 어댑터는 다른 랜덤 넘버 엔진을 엔트로피 소스로 사용하여 의사 난수를 생성합니다. 일반적으로 기본 엔진의 스펙트럼 특성을 변경하는 데 사용됩니다.
|
헤더 파일에 정의됨
<random>
|
|
|
(C++11)
|
난수 엔진의 일부 출력을 버림
(클래스 템플릿) |
|
(C++11)
|
난수 엔진의 출력을 지정된 비트 수의 블록으로 패킹
(클래스 템플릿) |
|
(C++11)
|
난수 엔진의 출력을 다른 순서로 전달
(클래스 템플릿) |
미리 정의된 난수 생성기
여러 구체적인 인기 알고리즘이 미리 정의되어 있습니다.
|
헤더에 정의됨
<random>
|
|
| 유형 | 정의 |
minstd_rand0
(C++11)
|
std::
linear_congruential_engine
<
std::
uint_fast32_t
,
16807
,
0
,
2147483647
>
1969년 Lewis, Goodman 및 Miller가 발견하고, 1988년 Park과 Miller에 의해 "최소 표준"으로 채택됨 |
minstd_rand
(C++11)
|
std::
linear_congruential_engine
<
std::
uint_fast32_t
,
|
mt19937
(C++11)
|
std::
mersenne_twister_engine
<
std::
uint_fast32_t
,
|
mt19937_64
(C++11)
|
std::
mersenne_twister_engine
<
std::
uint_fast64_t
,
|
ranlux24_base
(C++11)
|
std:: subtract_with_carry_engine < std:: uint_fast32_t , 24 , 10 , 24 > |
ranlux48_base
(C++11)
|
std:: subtract_with_carry_engine < std:: uint_fast64_t , 48 , 5 , 12 > |
ranlux24
(C++11)
|
std::
discard_block_engine
<
std::
ranlux24_base
,
223
,
23
>
24비트 RANLUX 생성기 (Martin Lüscher와 Fred James, 1994) |
ranlux48
(C++11)
|
std::
discard_block_engine
<
std::
ranlux48_base
,
389
,
11
>
48비트 RANLUX 생성기 (Martin Lüscher와 Fred James, 1994) |
knuth_b
(C++11)
|
std:: shuffle_order_engine < std:: minstd_rand0 , 256 > |
philox4x32
(C++26)
|
std::
philox_engine
<
std::
uint_fast32_t
,
32
,
4
,
10
,
0xCD9E8D57
,
0x9E3779B9
,
0xD2511F53
,
0xBB67AE85
>
|
philox4x64
(C++26)
|
std::
philox_engine
<
std::
uint_fast64_t
,
64
,
4
,
10
,
0xCA5A826395121157
,
0x9E3779B97F4A7C15
,
0xD2E7470EE14C6C93
,
0xBB67AE8584CAA73B
>
|
default_random_engine
(C++11)
|
구현 정의 RandomNumberEngine 타입 |
비결정적 난수
std::random_device 는 비결정적 균일 난수 비트 생성기입니다. 하지만 비결정적 난수 생성에 대한 지원이 없는 경우 구현체가 std::random_device 를 의사 난수 엔진을 사용하여 구현하는 것이 허용됩니다.
|
(C++11)
|
하드웨어 엔트로피 소스를 사용하는 비결정적 난수 생성기
(클래스) |
난수 분포
난수 분포는 URBG의 출력을 사후 처리하여 결과 출력이 정의된 통계적 확률 밀도 함수에 따라 분포되도록 합니다.
난수 분포는 RandomNumberDistribution 요구 사항을 충족합니다.
|
헤더에 정의됨
<random>
|
|
균일 분포 |
|
|
(C++11)
|
범위 내에서 균일하게 분포된 정수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
범위 내에서 균일하게 분포된 실수 값을 생성합니다
(클래스 템플릿) |
베르누이 분포 |
|
|
(C++11)
|
bool
값을
베르누이 분포
기반으로 생성합니다
(클래스) |
|
(C++11)
|
이항 분포
상의 정수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
음이항 분포를 따르는 정수 값을 생성합니다
negative binomial distribution
(클래스 템플릿) |
|
(C++11)
|
기하 분포
상의 정수 값을 생성합니다
(클래스 템플릿) |
포아송 분포 |
|
|
(C++11)
|
푸아송 분포
상의 정수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
지수 분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
감마 분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
Weibull distribution
에 따른 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
극값 분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
정규 분포 |
|
|
(C++11)
|
표준 정규 (가우시안) 분포
에서 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
로그 정규 분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
카이제곱 분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
코시 분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
Fisher의 F-분포
상의 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
실수 값을
스튜던트 t-분포
에 따라 생성함
(클래스 템플릿) |
표본 분포 |
|
|
(C++11)
|
이산 분포에서 정수 값을 생성함
(클래스 템플릿) |
|
(C++11)
|
일정한 부분 구간에 분포된 실수 값을 생성합니다
(클래스 템플릿) |
|
(C++11)
|
정의된 부분 구간에 분포된 실수 값을 생성합니다
(클래스 템플릿) |
유틸리티
|
헤더 파일에 정의됨
<random>
|
|
|
(C++11)
|
주어진 정밀도의 실수 값을
[
0
,
1
)
구간에 균일하게 분포시킴
(함수 템플릿) |
|
(C++11)
|
범용 편향 제거 스크램블 시드 시퀀스 생성기
(클래스) |
난수 알고리즘
|
헤더 파일에 정의됨
<random>
|
|
|
(C++26)
|
범위를 균일 난수 비트 생성기로부터 생성된 난수로 채움
(알고리즘 함수 객체) |
C 랜덤 라이브러리
위에서 설명한 엔진과 분포 외에도, C 랜덤 라이브러리의 함수와 상수들도 사용 가능하지만 권장하지 않습니다:
|
헤더 파일에 정의됨
<cstdlib>
|
|
|
의사 난수 생성
(함수) |
|
|
의사 난수 생성기 시드 설정
(함수) |
|
|
std::rand
가 생성할 수 있는 최댓값
(매크로 상수) |
|
예제
#include <cmath> #include <iomanip> #include <iostream> #include <map> #include <random> #include <string> int main() { // 실제 랜덤 값으로 시드 설정 (사용 가능한 경우) std::random_device r; // 1과 6 사이의 랜덤 평균값 선택 std::default_random_engine e1(r()); std::uniform_int_distribution<int> uniform_dist(1, 6); int mean = uniform_dist(e1); std::cout << "무작위로 선택된 평균: " << mean << '\n'; // 해당 평균을 중심으로 정규 분포 생성 std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()}; std::mt19937 e2(seed2); std::normal_distribution<> normal_dist(mean, 2); std::map<int, int> hist; for (int n = 0; n != 10000; ++n) ++hist[std::round(normal_dist(e2))]; std::cout << "정규 분포 (평균 " << mean << "):\n" << std::fixed << std::setprecision(1); for (auto [x, y] : hist) std::cout << std::setw(2) << x << ' ' << std::string(y / 200, '*') << '\n'; }
가능한 출력:
무작위로 선택된 평균: 4 정규 분포 (평균 4): -4 -3 -2 -1 0 * 1 *** 2 ****** 3 ******** 4 ********* 5 ******** 6 ****** 7 *** 8 * 9 10 11 12
참고 항목
|
C 문서
for
의사 난수 생성
|