Скорректировать алгоритм генерации случайных значений силы
Несколько дней назад вы помогли мне найти алгоритм для генерации случайных значений силы в онлайн-игре (особенно Джон Раш).
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 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
до случайной мощности, чтобы преобразовать его обратно в диапазон логарифмов.
Одним из способов было бы просто масштабировать значения:
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;
}
Масштабировать и перемещать распределение в нормализованном диапазоне:
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