문제

정수 범위의 시작과 끝이 주어지면이 범위 사이의 정규 분포 임의 정수를 어떻게 계산합니까?

나는 정규 분포가 -+ 무한대로 들어간다는 것을 알고 있습니다. 테일이 컷오프 될 수 있다고 생각합니다. 따라서 무작위가 범위 밖에서 계산되면 재판매합니다. 이것은 범위에서 정수의 확률을 높이지만,이 효과가 허용 가능한 한 (<5%) 괜찮습니다.

public class Gaussian
{
    private static bool uselast = true;
    private static double next_gaussian = 0.0;
    private static Random random = new Random();

    public static double BoxMuller()
    {
        if (uselast) 
        { 
            uselast = false;
            return next_gaussian;
        }
        else
        {
            double v1, v2, s;
            do
            {
                v1 = 2.0 * random.NextDouble() - 1.0;
                v2 = 2.0 * random.NextDouble() - 1.0;
                s = v1 * v1 + v2 * v2;
            } while (s >= 1.0 || s == 0);

            s = System.Math.Sqrt((-2.0 * System.Math.Log(s)) / s);

            next_gaussian = v2 * s;
            uselast = true;
            return v1 * s;
        }
    }

    public static double BoxMuller(double mean, double standard_deviation)
    {
        return mean + BoxMuller() * standard_deviation;
    }

    public static int Next(int min, int max)
    {
        return (int)BoxMuller(min + (max - min) / 2.0, 1.0); 
    }
}

아마도 표준 편차를 범위와 관련시키는 방법을 확장해야하지만 방법을 이해하지 못합니다.

대답:

    // Will approximitely give a random gaussian integer between min and max so that min and max are at
    // 3.5 deviations from the mean (half-way of min and max).
    public static int Next(int min, int max)
    {
        double deviations = 3.5;
        int r;
        while ((r = (int)BoxMuller(min + (max - min) / 2.0, (max - min) / 2.0 / deviations)) > max || r < min)
        {
        }

        return r;
    }
도움이 되었습니까?

해결책

Box-Muller 메소드가 "표준"정규 분포를 반환하면 평균 0 및 표준 편차가 나타납니다. 표준 정규 분포를 변환하려면 임의 숫자에 x를 곱하여 표준 편차 x를 얻습니다. 메모리가 저를 올바르게 제공하는 경우 평균 y.

참조 표준 정규 변수 정규화에 관한 Wikipedia 기사 섹션 (속성 1) 보다 공식적인 증거를 위해.


귀하의 의견에 따라 경험의 규칙은 정규 분포의 99.7%가 표준 편차의 +/- 3 배 이내에 있다는 것입니다. 예를 들어 0에서 100까지의 정규 분포가 필요한 경우 평균보다 중간이되고 SD는 (100/2)/3 = 16.667입니다. 따라서 Box-Muller 알고리즘에서 얻는 값이 16.667을 곱하여 분포를 "스트레치"한 다음 50을 "중심"에 추가하십시오.


John, 당신의 최신 의견에 대한 응답으로, 나는 정말로 Next 기능. 그것은 항상 1의 표준 편차와 최소와 최대 사이의 절반의 평균을 사용합니다.

y 평균을 원한다면 -x에서 +x 범위의 숫자의 ~ 99.7%가 BoxMuller(Y, X/3).

다른 팁

글쎄, -2*시그마 ..+2*시그마는 벨 곡선의 95%를 줄 것입니다. (이미 언급 된 Wiki 기사에서 "표준 편차 및 신뢰 구간"섹션을 확인하십시오).

따라서이 부분을 수정하십시오.

return (int)BoxMuller(min + (max - min) / 2.0, 1.0);

1.0 (표준 편차)을 2.0으로 변경하십시오 (또는 95% 이상을 원하는 경우 더 많은 경우)

return (int)BoxMuller(min + (max - min) / 2.0, 2.0);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top