Настроить алгоритм генерации случайных значений силы - PullRequest
3 голосов
/ 03 июня 2009

Несколько дней назад, вы помогли мне найти алгоритм генерации случайных значений силы в онлайн-игре (особенно Джон Раш) .

function getRandomStrength($quality) {
    $rand = mt_rand()/mt_getrandmax();
    $value = round(pow(M_E, ($rand - 1.033) / -0.45), 1);
    return $value;
}

Эта функция генерирует значения от 1,1 до 9,9. Теперь я хочу настроить эту функцию так, чтобы она давала значения той же вероятности, но в другом интервале, например 1,5-8,0. Было бы идеально, если бы вы могли добиться этого с помощью дополнительных параметров.

Было бы здорово, если бы вы могли мне помочь. Заранее спасибо!

Ответы [ 3 ]

5 голосов
/ 04 июня 2009

Значения 1.033 и -0.45 в исходном коде являются магическими числами, которые обеспечивают шкалу 1.1 - 9.9. Вы должны получить те же результаты, если вы передадите в 1.1 и 9.9 параметры $low и $high в следующем коде.

function getRandomStrength($low, $high) {
    // TODO: validate the input
    $ln_low = log( $low, M_E );
    $ln_high = log( $high, M_E );
    $scale = $ln_high - $ln_low;

    $rand = ( mt_rand() / mt_getrandmax() ) * $scale + $ln_low;
    $value = round( pow( M_E, $rand), 1 );
    return $value;
}

Вы должны иметь возможность пройти в любом диапазоне для $low и $high и получить логарифмическое распределение в этом диапазоне. (Я оставлю вам проверку допустимости диапазона, но 0 <<code>$low <<code>$high должно быть истинным.)

Это работает путем обратного расчета линейной шкалы, необходимой для генерации логарифмической шкалы в заданном диапазоне. Например, если я хочу, чтобы моя шкала лога была 1,1 - 9,9, я беру натуральное логарифм каждого из этих значений, давая мне 0,0953 - 2,2925. Затем я генерирую случайное число в этом линейном диапазоне и увеличиваю e до случайной степени, чтобы преобразовать его обратно в лог-диапазон.

3 голосов
/ 03 июня 2009

Одним из способов было бы просто масштабировать значения:

function getRandomStrength($quality,$min,$max) {
    $rand = mt_rand()/mt_getrandmax();
    $value = round(pow(M_E, ($rand - 1.033) / -0.45), 1);
    $value = $value - 1.1
    $value = $value * ((max-min) / 8.8)
    $value = $value + $min
    return $value;
}
2 голосов
/ 03 июня 2009

Масштабирование и смещение распределения в нормированном диапазоне:

D(a,b) = (D(0,1)*(b-a))+a

Чтобы сначала получить D (0,1) из исходной функции D (c, d), выполните обратное:

D(0,1) = (D(c,d)-c)/(d-c)

В вашем случае D - исходная функция (экспоненциальная функция), a равно 1,5, b равно 8,5, c равно 1,1 и d равно 9,9

...