分裂概率
我在 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 个片段:
- 第一个片段的概率为 10% * 10 = 1
- 第二个片段的概率为 20% * 10 = 2
- 第三个片段的概率为 30% * 10 = 3
- 第四个片段的概率为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:
- the first one having a probability of 10% * 10 = 1
- the second one having a probability of 20% * 10 = 2
- the third one having a probability of 30% * 10 = 3
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
确实你是!
在第二遍中,每次给它 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.
如果您期望
DoIt_02()
返回与DoIt_01()
相同数量的结果,那么是的,您犯了一个基本的数学错误。 您的部分的概率权重总计为 10 没有任何意义,因为加权机会不会应用于整个 0..240 集。 如果您在 0..240 而不是 0..59、60..119 等上运行每个受限概率,它会返回类似的结果。顺便说一句,您的
Chance()
函数在这方面略有偏差,要获得您似乎正在尝试的概率,它应该是mt_rand(1, $universe) <= $chance
或mt_rand(0, $universe - 1)
mt_rand(0, $universe - 1)
$机会
。If you're expecting
DoIt_02()
to return about the same number of results asDoIt_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 eithermt_rand(1, $universe) <= $chance
ormt_rand(0, $universe - 1) < $chance
.