分裂概率

发布于 2024-07-18 15:45:08 字数 1852 浏览 4 评论 0原文

我在 PHP 中有以下代码,运行良好(每次运行时返回或多或少 10 个结果):

function GetAboutTenRandomNumbers()
{
    $result = array();

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

    echo '<pre>';
    print_r($result);
    echo '</pre>';

    return $result;
}

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,因此我编写了以下函数来执行此操作。

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 '</pre>';

    return $result;
}

问题是我已经运行 GetAboutTenWeightedRandomNumbers 函数数十次,结果比 GetAboutTenRandomNumbers 函数返回的结果低得多。 我确信我犯了一个基本的数学错误,我怀疑在哪里,但我不知道如何解决它。

I've the following code in PHP which works fine (returns more or less 10 results each time it runs):

function GetAboutTenRandomNumbers()
{
    $result = array();

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

    echo '<pre>';
    print_r($result);
    echo '</pre>';

    return $result;
}

And the Chance() function goes as follows:

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

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

    return false;
}

Now, I want to randomly split those 10 (on average) results in the 4 following segments:

  1. the first one having a probability of 10% * 10 = 1
  2. the second one having a probability of 20% * 10 = 2
  3. the third one having a probability of 30% * 10 = 3
  4. the fourth one having a probability of 40% * 10 = 4

As you can see the sum of all segments (1 + 2 + 3 + 4) equals 10, so I've coded the following function to do this.

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 '</pre>';

    return $result;
}

The problem is I've run the GetAboutTenWeightedRandomNumbers function dozens of times and the result is much more lower than the result returned by the GetAboutTenRandomNumbers function. I'm sure that I'm making a fundamental math mistake, I suspect where but I don't know how to solve it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冰葑 2024-07-25 15:45:09

确实你是!

在第二遍中,每次给它 60 个值,而不是 240 个,因此您将在该遍中获得大约四分之一的预期值。 将每个运行到 240 并使用模 60 来获取您在每个循环中查找的值的范围。

Indeed you are!

In your second pass, you're giving it 60 values each pass, instead of 240, so you'll get about a quarter of the expected values in that pass. Run each to 240 and use a modulo 60 to get the range of values you're looking for in each loop.

半岛未凉 2024-07-25 15:45:09

如果您期望 DoIt_02() 返回与 DoIt_01() 相同数量的结果,那么是的,您犯了一个基本的数学错误。 您的部分的概率权重总计为 10 没有任何意义,因为加权机会不会应用于整个 0..240 集。 如果您在 0..240 而不是 0..59、60..119 等上运行每个受限概率,它会返回类似的结果。

顺便说一句,您的 Chance() 函数在这方面略有偏差,要获得您似乎正在尝试的概率,它应该是 mt_rand(1, $universe) <= $chancemt_rand(0, $universe - 1) mt_rand(0, $universe - 1) $机会

If you're expecting DoIt_02() to return about the same number of results as DoIt_01(), then yeah, you're making a fundamental math mistake. Your sections' probability weights summing to 10 means nothing because the weighted chances aren't applied to the entire 0..240 set. It would return similar results if you ran each restricted probability on 0..240 instead of 0..59, 60..119, etc.

Incidentally, your Chance() function is slightly off in that, to get the probabilities you seem to be trying for, it should be either mt_rand(1, $universe) <= $chance or mt_rand(0, $universe - 1) < $chance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文