Моя задача:
Генерация случайных чисел от 1 до 20 с точностью до 1 десятичного знака.
Однако моя проблема так же проста, как mt_rand. Я хочу, чтобы большинство сгенерированных чисел было меньше примерно на 0,5–4,5, иногда между 4,5–10 и очень редко, если раз в 12–20 часов было между 10–20.
Я использовал следующее, но не знаю, с чего начать. Я очень простой программист-самоучка.
$min = 1;
$max = 20;
$suisse_interest = mt_rand ($min*10, $max*10) / 10
Может быть, если я вкратце объясню, зачем мне это нужно, это поможет ..
У меня есть онлайн-игра, и я хочу добавить 3 «банка», каждый из которых будет приносить разные проценты каждый час. В большинстве случаев я хочу, чтобы он был низким, но иногда и выше и очень редко очень высоким (15-20%).
В приведенном выше коде случайное число становится слишком большим или часто.
Любая помощь в этом приветствуется!
3 ответа
Попробуйте это. Вероятность 1,0 ~ 4,5 составляет около 96%, 4,5 ~ 10,0 - около 2%, а 10,0 ~ 20,0 - около 2%.
<?php
// 1.0~4.5 96%
// 4.5~10.0 2%
// 10.0~20.0 2%
function fun() {
$num = mt_rand(1, 100);
if ($num > 0 && $num <= 96) {
$return = mt_rand(10, 45) / 10; // 96%
} else if ($num > 96 && $num <= 98) {
$return = mt_rand(45, 100) / 10; // 2%
} else {
$return = mt_rand(100, 200) / 10; // 2%
}
return sprintf("%01.1f",$return);
}
echo fun();
?>
Это не проблема PHP.
Что вам нужно, так это нелинейный вероятностный закон, который затем можно реализовать в PHP.
Если вы хотите, чтобы что-то основывалось на среднем значении, идеальным было бы гауссовское или нормальное распределение, но его вычисление требует различных сложных приемов, большинство из которых оптимизировано для быстрой генерации за счет увеличения сложности.
Если вы генерируете только несколько значений каждый час, производительность не будет проблемой.
Разумным приближением было бы суммирование 3 или 4 случайных величин с использованием центральной предельной теоремы .
Суммирование случайных значений от 0 до двойного среднего значения создаст приближение гауссовского значения с центром вокруг вашего среднего значения. Затем вы можете ограничить значения ниже средней, если вам не нужны низкие значения. В конечном итоге шансы получить среднюю ставку будут составлять 50%, а шанс получить вдвое большую ставку будет постоянно снижаться.
Увеличение числа сумм «сузит» кривую, уменьшая вероятность получения высокого значения.
Например:
define ("INTEREST_MEAN", 10);
define ("INTEREST_SPREAD", 5);
function random_interest ()
{
$res = 0;
for ($i = 0 ; $i != INTEREST_SPREAD ; $i++) $res += mt_rand(0, 2*INTEREST_MEAN);
$res /= INTEREST_SPREAD; // normalize the sum to get a mean-centered result
$res = max ($res, INTEREST_MEAN); // clamp lower values
}
Вам нужен экспоненциальный расчет. Если вы используете функцию, подобную следующей, вероятность малых чисел возрастает. Конечно, вам нужно немного изменить числа, чтобы результат соответствовал вашим потребностям.
$i = 0;
while($i<30) {
$i++;
$rand = mt_rand(0, 7000) / 100; // 0.0 ~ 70.0
// This is the most important line:
$output = round( 20*(pow(0.95,$rand)) , 1);
echo "$output ";
}
Пример вывода:
1.8 4.3 2.6 5.5 3.7 15.5 1.6 0.6 0.6 1.6 5.8 1.3 6.1 3.2 0.8 1.7 14.7 7.9 1.3 10.3 5.5 12.6 1.5 8.4 1.5 0.9 13.3 5.8 7.5 1.7
Как видите, печатается в основном меньшее количество.
Вероятность получить 20
в моем коде составляет около 1.4%
, тогда как вероятность получить число smaller than 5
составляет около 78%
Похожие вопросы
Связанные вопросы
Новые вопросы
php
PHP — это широко используемый язык сценариев общего назначения с открытым исходным кодом, мультипарадигмальный, динамически типизированный и интерпретируемый, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.