Алгоритм кривой Белла с PHP - PullRequest
1 голос
/ 04 марта 2011

Я работаю над личным проектом, в котором диапазоны IQ будут случайным образом назначаться поддельным персонажам.Это распределение будет случайным, но реалистичным, поэтому диапазоны IQ должны быть распределены вдоль кривой колокола.Существует 3 категории диапазона: низкий, нормальный и высокий.Половина фальшивых символов попадет в нормальный режим, но около 25% попадет либо в нижний, либо в верхний диапазон.

Как я могу закодировать это?

Ответы [ 4 ]

5 голосов
/ 04 марта 2011

Это может выглядеть долго и сложно (и было написано процедурно для PHP4), но я использовал следующее для генерации нелинейных случайных распределений:

function random_0_1()
{
    //  returns random number using mt_rand() with a flat distribution from 0 to 1 inclusive
    //
    return (float) mt_rand() / (float) mt_getrandmax() ;
}

function random_PN()
{
    //  returns random number using mt_rand() with a flat distribution from -1 to 1 inclusive
    //
    return (2.0 * random_0_1()) - 1.0 ;
}


function gauss()
{
    static $useExists = false ;
    static $useValue ;

    if ($useExists) {
        //  Use value from a previous call to this function
        //
        $useExists = false ;
        return $useValue ;
    } else {
        //  Polar form of the Box-Muller transformation
        //
        $w = 2.0 ;
        while (($w >= 1.0) || ($w == 0.0)) {
            $x = random_PN() ;
            $y = random_PN() ;
            $w = ($x * $x) + ($y * $y) ;
        }
        $w = sqrt((-2.0 * log($w)) / $w) ;

        //  Set value for next call to this function
        //
        $useValue = $y * $w ;
        $useExists = true ;

        return $x * $w ;
    }
}

function gauss_ms( $mean,
                   $stddev )
{
    //  Adjust our gaussian random to fit the mean and standard deviation
    //  The division by 4 is an arbitrary value to help fit the distribution
    //      within our required range, and gives a best fit for $stddev = 1.0
    //
    return gauss() * ($stddev/4) + $mean;
}

function gaussianWeightedRnd( $LowValue,
                                 $maxRand,
                                 $mean=0.0,
                                 $stddev=2.0 )
{
    //  Adjust a gaussian random value to fit within our specified range
    //      by 'trimming' the extreme values as the distribution curve
    //      approaches +/- infinity
    $rand_val = $LowValue + $maxRand ;
    while (($rand_val < $LowValue) || ($rand_val >= ($LowValue + $maxRand))) {
        $rand_val = floor(gauss_ms($mean,$stddev) * $maxRand) + $LowValue ;
        $rand_val = ($rand_val + $maxRand) / 2 ;
    }

    return $rand_val ;
}

function bellWeightedRnd( $LowValue,
                             $maxRand )
{
    return gaussianWeightedRnd( $LowValue, $maxRand, 0.0, 1.0 ) ;
}

Для простого распределения звонков просто вызовите bellWeightedRnd() с минимальным и максимальным значениями;для более изощренного распределения gaussianWeightedRnd () позволяет вам также указать среднее значение и stdev для вашего распределения.

Гауссова колокольня хорошо подходит для распределения IQ, хотя у меня также есть аналогичные процедуры для альтернативных кривых распределениятакие как пуассон, гамма, логарифмическая и т. д.

1 голос
/ 04 марта 2011

сначала предположим, что у вас есть 3 функции для обеспечения высокого среднего и низкого IQ, затем просто

function randomIQ(){
    $dice = rand(1,100);
    if($dice <= 25) $iq = low_iq();
    elseif($dice <= 75) $iq = medium_iq();
    else $iq = high_iq();
    return $iq;
}
0 голосов
/ 04 марта 2011

Используя ссылку , которую он опубликовал, я создал следующую функцию:

function RandomIQ()
{  
    return round((rand(-1000,1000) + rand(-1000,1000) + rand(-1000,1000))/100,0) * 2 + 100;
}   

Это немного грязно, но некоторая быстрая проверка дает среднее значение примерно 100 и примерно нормальное распределение,Он должен соответствовать информации, полученной с этого сайта .

0 голосов
/ 04 марта 2011

Вы можете рандомизировать несколько «кубиков», случайное число от каждого сложения до наивысшей точки. Это создаст нормальное распределение (приблизительно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...