2011-03-14 2 views
8

바로 지금 다음 코드를 사용하여 범위가있는 정수의 균일 한 분포를 만듭니다. 내가 twords 최소 값을 선호 분포를주고 그것을 수정하려고하지 않으며, 거의 절대 생산하는 최대 값에 가까워하고tr1을 사용하여 비 균일 한 정수 분포 생성

int random(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::uniform_int<int> dist(min, max); 
    return dist(gen); 

} 

(I는 시드 코드를했다). 미리 만들어진 분포를 모두 볼 수는 있지만 정수는 아닙니다. 또한 어느 문서에 기반하여 어느 것이 나의 요구에 맞는지 알 수 없습니다. 정수와 함께 사용 혼자 설정을하게하는 방법을 documentation에 따라, k는 = 2

하지만 알아낼 수 없습니다 위키 피 디아에 같이 내가 온 가장 가까운 카이 유통 제곱입니다 k 값.

적절한 비 균일 한 정수 분포를 사용하도록 함수를 설정하려면 어떻게해야합니까? 0이 1보다 더 자주해야로서, 확실히이

아직,하지만 도움이 될 것입니다 여기에 0 ~ 20에서 std::poisson_distribution<int> dist((max - min) * .1);의 결과는 다음과 같습니다


는 여전히 올바른 배포판을 선택하는 작업 다음 사람은 나와서 더 많은 결과를 올릴 것입니다.

int randomDist(int min, int max) 
{ 
    static std::mt19937 gen; 
    std::chi_squared_distribution<double> dist(2); 

    int x; 
    do 
    { 
    x = (int)(max*dist(gen)/10) + min; 
    } 
    while (x > max); 
    return x; 
} 

의 결과 제공 :


아니라 내 최종 솔루션이 방법의 조합이되었다

+0

포아송 분포에서 1보다 작은 매개 변수를 선택하면 0이 더 빈번합니다 (현재 (20-0) * .1 = 2). 또한 매개 변수가있는 기하 분포를 사용하여이를 얻을 수 있습니다. 당신이 선택해야하는 것은 당신이 모델링하는 것에 달려 있습니다 : 기하학적 모델 (time) : 이벤트가 발생할 때까지의 시간 (예를 들어, 골을 넣는 데 필요한 샷 수), 포아송은 일정 시간 간격으로 숫자 이벤트 발생을 모델링합니다 게임의 목표). – aaz

+1

그럼 실시간 유전자 알고리즘에 사용하고 있습니다. 차별화 된 세대를 갖는 대신, 새로운 유기체를 번식시킬 때가되면, 나는이 곡선을 기반으로 한 부모를 선택하여 적합성에 따라 분류합니다. – Zak

+0

@Zak - 기하학적 분포를 사용하여 선택하면 각 부모의 선택을 # 1 대 vs (# 3 대 v ...)의 우승자로 묘사 할 수 있습니다. 여기서 #i가 우승합니다 확률 p를 가진 어떤 #j, i aaz

답변

9

다른 정수 분포가 있습니다를, 그들은 단지하지 않습니다 그들의 이름에 int이 있으십시오. 클래스 정의에는 typedef IntType result_type이 있습니다.

당신이 설명하는대로 작동 사람은 : 당신이로 범위를 번역해야

  • binomial_distribution(t, p)

    이 범위의 숫자를 생성 0 ≤ X≤, 그래서 min. 평균은 t · P에, 그래서이 숫자 0 ≤ X < ∞하지만, 많은 수의 생성 0

    std::binomial_distribution<int> dist(max - min, .1);
    return dist(gen) + min;

  • poisson_distribution(λ)

    근처 페이지를을 선택 점차적으로 가능성이 적습니다. 범위를 제한하기 위해 max 이상의 모든 것을 검열 할 수 있습니다. 매개 변수 λ이 평균입니다.이를 선택하면 앞의 예와 일치한다 :

    std::poisson_distribution<int> dist((max - min) * .1);
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

  • geometric_distribution(p)

    는 또한 숫자를 생성 0 ≤ X < ∞이지만 가장 가능성있는 결과는 0이고 이후의 모든 숫자는 이전보다 적습니다.

    std::geometric_distribution<int> dist(1/((max - min) * .1 + 1));
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

당신은 또한에 연속 배포판 중 하나를 사용할 수 있습니다 다시 매개 변수를 선택하면 이전 예제의 평균에 맞게 double 생성 후 그것을 int에. 분포뿐만 아니라

6

그러나 실제로 가능한 경우에만 있음 (inverse transform sampling를 사용하여, 당신은 또한 당신이 생각할 수있는 확률 분포 함수에 균일 한 분포를 변화시킬 수 명심,의 큰 대답 @aaz 했다 일부 "좋은"기능) 또는 rejection sampling (어떤 경우에도 적용 할 수 있지만 계산 상 비쌉니다).

그것은 나에게 보인다

사용자의 요구에 딱 맞는 분포는 exponential distribution (음)이 될 것이라고 :

Exponential distribution

다행히, 당신이 역 샘플링 변환을 적용 할 수있는에 분포 중 하나입니다, p

x = - ln(1-p)/lambda 

는 랜덤 브로이다 이는 균일로부터 샘플을 가지고 [0, 1] 분포 수식을 적용하여 지수 분포를 얻을 수 있음을 의미 ue는 균일 분포에서이고 lambda은 지수 분포의 매개 변수입니다. 자세한 내용은 here을 참조하십시오.

당신이 x의 (a double 될 것이다), 단지 (같은 기능으로 또는 둘레 :

int round(double val) 
{ 
    // warning: can give counterintuitive results with negative numbers 
    return int(val+0.5); 
} 

) int에 캐스팅 일단 당신의 결과를 얻을 수 있습니다.


그런데 편집

, 심지어 지수 분포가 이미 <random> (link)에 포함되어 있는지 알아 차리지 않았다 ... 글쎄, 더 나은, 당신은하지 않습니다 코드를 작성해야하지만 이론의 약간은 낭비 적이 결코 :)입니다.

관련 문제