Вероятности расщепления - PullRequest
1 голос
/ 11 мая 2009

У меня есть следующий код в PHP, который работает нормально (возвращает более или менее 10 результатов при каждом запуске):

<code>function GetAboutTenRandomNumbers()
{
    $result = array();

    for ($i = 0; $i < 240; $i++)
    {
        if (Chance(10, 240) === true)
        {
            $result[] = $i;
        }
    }

    echo '<pre>';
    print_r($result);
    echo '
'; вернуть $ результат; }

А функция Chance () работает следующим образом:

function Chance($chance, $universe = 100)
{
    $chance = abs(intval($chance));
    $universe = abs(intval($universe));

    if (mt_rand(1, $universe) <= $chance)
    {
        return true;
    }

    return false;
}

Теперь я хочу случайным образом разделить эти 10 (в среднем) результатов на 4 следующих сегмента:

  1. первый имеет вероятность 10% * 10 = 1
  2. второй с вероятностью 20% * 10 = 2
  3. третий с вероятностью 30% * 10 = 3
  4. четвертый с вероятностью 40% * 10 = 4

Как видите, сумма всех сегментов (1 + 2 + 3 + 4) равна 10, поэтому для этого я написал следующую функцию:

<code>function GetAboutTenWeightedRandomNumbers()
{
    $result = array();

    // Chance * 10%
    for ($i = 0; $i < 60; $i++)
    {
        if (Chance(10 * 0.1, 240) === true)
        {
            $result[] = $i;
        }
    }

    // Chance * 20%
    for ($i = 60; $i < 120; $i++)
    {
        if (Chance(10 * 0.2, 240) === true)
        {
            $result[] = $i;
        }
    }

    // Chance * 30%
    for ($i = 120; $i < 180; $i++)
    {
        if (Chance(10 * 0.3, 240) === true)
        {
            $result[] = $i;
        }
    }

    // Chance * 40%
    for ($i = 180; $i < 240; $i++)
    {
        if (Chance(10 * 0.4, 240) === true)
        {
            $result[] = $i;
        }
    }

    echo '<pre>';
    print_r($result);
    echo '
'; вернуть $ результат; }

Проблема в том, что я запускал функцию GetAboutTenWeightedRandomNumbers десятки раз, и результат намного ниже, чем результат, возвращаемый функцией GetAboutTenRandomNumbers. Я уверен, что совершаю фундаментальную математическую ошибку, подозреваю, где, но я не знаю, как ее исправить.

Ответы [ 2 ]

3 голосов
/ 11 мая 2009

Да, действительно!

Во втором проходе вы даете ему 60 значений за каждый проход вместо 240, так что вы получите около четверти ожидаемых значений за этот проход. Подведите каждый к 240 и используйте модуль 60 для получения диапазона значений, который вы ищете в каждом цикле.

2 голосов
/ 11 мая 2009

Если вы ожидаете, что DoIt_02() выдаст примерно такое же количество результатов, как и DoIt_01(), то да, вы делаете фундаментальную математическую ошибку. Веса вероятности ваших секций, суммирующие до 10, ничего не значат, потому что взвешенные шансы не применяются ко всему набору 0..240. Он даст аналогичные результаты, если вы запустите каждую ограниченную вероятность на 0..240 вместо 0..59, 60..119 и т. Д.

Кстати, ваша функция Chance() слегка отключена, чтобы получить вероятности, которые вы, похоже, пытаетесь найти, она должна быть либо mt_rand(1, $universe) <= $chance, либо mt_rand(0, $universe - 1) < $chance.

...