본문 바로가기

Programming/CPP11&14

[C++11] 새로워진 random number 생성

반응형

난수(Random number) 생성은 일반적으로 확률 값이 필요한 경우에 사용이 됩니다.

프로그래밍을 처음 배울 때, 로또 번호 생성기를 제작할 때 쓰이기도 합니다.

그 외에 난수를 기반으로 하는 암호화에도 활용이 됩니다.

기존의 난수 생성은 다음과 같습니다.

#include <stdlib.h>
#include <time.h>
#include <iostream>

int main()
{
	srand((int)time(0));
	int nRand1 = rand();
	int nRand2 = rand() % 11;

	std::cout << nRand1 << std::endl;
	std::cout << nRand2 << std::endl;

	return 0;
}

통 범위 내의 값을 얻을 때 나머지 연산을 통해서 값을 얻게 됩니다.

nRand2는 0~10 사이의 임의의 숫자를 얻을 수 있습니다.

C++11에 새로운 random이 추가되었습니다.

C++11의 random은 generators와 distributions으로 구분되어 있습니다.

Generators

균일하게 분포된 숫자를 생성

Distributions

특정 분포에 맞춰서 생성된 숫자를 변환

새로운 random은 <random> 헤더에 구현되어 있습니다.

먼저 generator 객체를 생성하고 distribution을 통해서 원하는 값을 추출합니다.

C++11 난수 생성 예제는 다음과 같습니다.

#include <random>
#include <chrono>
#include <set>
#include <iostream>

int main()
{
	auto current = std::chrono::system_clock::now();
	auto duration = current.time_since_epoch();
	auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();

	std::mt19937_64 genMT(millis);
	std::uniform_int_distribution<__int64> uniformDist(1, 45);

	std::cout << "Min Value : " << uniformDist.min() << std::endl;
	std::cout << "Max Value : " << uniformDist.max() << std::endl;

	// Make 6 random numbers.
	std::set<__int64> stLotto;
	while (6 > stLotto.size())
	{
		stLotto.insert(uniformDist(genMT));
	}

	// print 6 Numbers.
	for (auto nVal : stLotto)
	{
		std::cout << nVal << std::endl;
	}

	return 0;
}

mt19937_64라는 generator를 사용했습니다.

random에는 난수 생성을 위한 다양한 generator와 distribution을 선택할 수 있습니다.

그리고 C++11에 새로 추가된 chrono의 기능을 사용해서 seed값을 생성했습니다.

로또 번호 생성기로 작성하기 위해서 1~45까지의 숫자가 생성도록 distribution을 조정했습니다.

그리고 std::set 컨터이너에 6개 숫자를 생성해서 저장합니다.

std::set은 중복된 값을 허용하지 않기 때문에 동일한 값을 제외하고 6개 숫자를 생성할 수 있습니다.

새로운 random의 등장으로 좀 더 유용하게 난수를 생성할 수 있게 되었습니다.

반응형