2015-01-03 1 views
1

나는 메르 센 트위스터 PRNG를 실행되는 코드의 짧은 조각을 가지고 있고 그것을 잘 작동합니다 :함수 내에서 Mersenne Twister를 실행하는 방법은 무엇입니까?

std::random_device randDev; 
std::mt19937 twister(randDev()); 
std::uniform_int_distribution<int> dist(0,99); 

for (int i = 0; i < 10; i++) { 
    std::cout << dist(twister) << std::endl; 
} 

이 10 개 임의의 숫자를 출력합니다. 그러나 정확히 같은 코드를 함수에 넣으면 :

#include <random> 

int getRand(const int& A, const int& B) { 
    std::random_device randDev; 
    std::mt19937 twister(randDev()); 
    std::uniform_int_distribution<int> dist(A,B); 

    return dist(twister); 
} 

int main() { 
    for (int i = 0; i < 10; i++) { 
     std::cout << getRand(0,99) << std::endl; 
    } 

    return 0; 
} 

같은 번호를 10 번 출력합니다. 저는 C++로 시작했습니다. 그래서이 문제의 원인이나 문제 해결 방법을 모릅니다.

편집 : 문제는 std :: random_device에 있습니다. Eclipse C++ IDE (Luna 버전) 또는 MinGW 4.8.1의 버그 일 수 있지만 임의의 이유는 무엇이든간에 항상 동일한 숫자입니다. 나는 시간 (0)이 내 용도에 적합한 씨앗이 될 것이라고 믿습니다.

EDIT 2 : T.C.의 제안을 고려하고 시간 (0)이 여전히 같은 수의 열을 발생 시킨다는 사실은 지금까지 최종 코드입니다. 나는 rand()가 나쁘다는 것을 알지만 작동합니다.

#include <iostream> 
#include <random> 

std::mt19937 twister(rand()); 

int getRand(const int& A, const int& B) { 
    std::uniform_int_distribution<int> dist(A,B); 

    return dist(twister); 
} 

int main() { 
    for (int i = 0; i < 10; i++) { 
     std::cout << getRand(0,99) << std::endl; 
    } 

    return 0; 
} 
+0

어떤 컴파일러를 사용하고 있습니까? 이것은'g ++ - 4.9'를 사용하여 나에게 잘 맞습니다. – user14717

+0

첫 번째 경우에는 항상 임의의 값 순서를 얻습니까? – didierc

+0

저는 MinGW를 사용합니다. 실제로 제가 확인한 바로는, 첫 번째 코드에서 각각 동일한 10 개의 난수를 얻습니다. –

답변

0

어떤 컴파일러와 OS를 사용합니까? Visual Studio 2012 (2013 년은 확실하지 않음)에는 std :: random_device의 실제 구현이 없었습니다. 즉, 매번 동일한 값으로 초기화되었으므로 매번 동일한 시드로 초기화 된 메르 센 트위스터를 가질 수 있습니다. , 따라서 동일한 결과.

그리고 그런데

는 같은 질문에 질문을 받았다 것으로 보인다 : Windows에서

Why do I get the same sequence for every run with std::random_device with mingw gcc4.8.1?

그래서 분명히 GCC4.8는 의사 난수로 구현 표준 : random_device 있습니다.

+0

MinGW에서 Eclipse C++ IDE (Luna)를 사용합니다. –

+0

제가 언급 한 스레드에서 답변을 정확히 당신이 무엇을 찾고 있다고 생각합니다 –

3

문제는 새로운 시드, 난수 생성기 및 함수가 호출 될 때마다 배포판을 만드는 것입니다. 이것은 이러한 클래스를 사용하는 올바른 방법이 아닙니다.

난수 생성기를 사용하는 적절한 방법은 한 번 생성하여 전체 프로그램에 필요한 횟수만큼 (또는 적어도 합리적으로 긴 시간) 사용하는 것입니다. 하나의 함수 형태로 :

#include <random> 
#include <iostream> 

int getRand(const int& A, const int& B) { 
    static std::random_device randDev; 
    static std::mt19937 twister(randDev()); 
    static std::uniform_int_distribution<int> dist; 

    dist.param(std::uniform_int_distribution<int>::param_type(A, B)); 
    return dist(twister); 
} 

int main() { 
    for (int i = 0; i < 10; i++) { 
     std::cout << getRand(0, 99) << std::endl; 
    } 

    return 0; 
} 

정적 변수는 처음 함수가 호출 될 때 초기화되고 모든 후속 호출에 대해 다시 사용됩니다.

+0

내 코드를 개선 주셔서 감사하지만,이 경우에는 사실 씨앗을 재현했다는 사실이 아니라 이클립스 또는 MinGW std :: random_device를 사용하여 버그를 재현했다. –

+1

GCC random_device 문제는 연결된 질문에서 잘 대답됩니다. 내 대답은 처음에 물어 본 질문에 대한 것이고 다른 사람들에게 유용 할 수 있습니다. – slajoie

관련 문제