Скорректировать алгоритм генерации случайных значений силы


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

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. Было бы идеально, если бы вы могли достичь этого с помощью дополнительных параметров.

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

Author: Community, 2009-06-03

3 answers

Значения 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 $low $high должно быть правдой.)

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

 5
Author: Bill the Lizard, 2009-06-04 14:42:19

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

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;
}
 3
Author: Jacob B, 2009-06-03 18:37:56

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

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

 2
Author: fortran, 2009-06-03 18:38:53