2015-02-22 5 views
4

Моя задача:Генерация случайных чисел Php

Производите случайные числа от 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%).

С приведенным выше кодом случайное число часто становится слишком высоким.

Любая помощь с этим очень ценится!

+0

возможно дубликат [Defining процент для случайного числа] (http://stackoverflow.com/questions/20790139/defining-percentage-for-random-number) – Rizier123

+0

Поскольку распределение вы хотите создать [монотонное уменьшение] (http://en.wikipedia.org/wiki/Monotonic_function), вы можете использовать алгоритм [ziggurat] (http://en.wikipedia.org/wiki/Ziggurat_algorithm) для отображения ваше распределение (равномерное) на тот, который вы хотите (который вы произвольно можете создать). Или вы можете использовать преобразование box muller, но оно менее эффективно (и, поскольку вы делаете это много, вам может потребоваться прекомпиляция таблиц, описанных в алгоритме зиггурата). – will

ответ

2

Попробуйте this.The вероятность до 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(); 
?> 
+0

Большое вам спасибо, это помогло массово. Теперь все это имеет смысл! –

+0

Еще раз вопрос, если вы не возражаете. Как я могу взять echo fun() и поместить его в свою базу данных. Я знаю, что ниже не будет смысла, но, возможно, это сделает мою цель более ясной. $ interest = (результат fun()) mysql_query ("UPDATE r $ game [0] _ $ tab [сутенер ] SET suisseint = $ interest WHERE id = $ user1no [id]; "); Спасибо! –

+0

Жаль из-за праздника Весны. Ваш SQL прав, проверьте структуру таблицы и повторите попытку. – Wilon

3

Вам необходим экспоненциальный расчет. Если вы используете функцию, аналогичную следующей функции, вероятность низких чисел увеличивается. Конечно, вам нужно немного адаптировать номера, чтобы обеспечить выход, соответствующий вашим потребностям.

$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

Как вы видите, в основном меньшее количество распечатываются.

Chart

Вероятность получить 20 вокруг 1.4% в моем коде, тогда вероятность получить ряд составляет около 78%

+0

Отлично, этот и другой ответ оба работали. Точно, что я был после! Благодаря! –

0

Это не проблема с PHP.

Что вам нужно, это нелинейный закон вероятности, который затем можно реализовать на PHP.

Если вы хотите, чтобы что-то было сосредоточено вокруг среднего значения, идеальным было бы gaussian aka normal distribution, но для его вычисления требуются различные сложные трюки, большинство из которых оптимизированы для быстрого генерации за счет увеличения сложности.

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

Разумным приближением было бы суммирование 3 или 4 случайных величин, используя central limit theorem.

Суммирование случайных значений между 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 
} 
Смежные вопросы