线性概率的单一概率检查可以通过以下方式轻松完成:
function checkWithProbability($probability=0.1, $length=10000)
{
$test = mt_rand(1, $length);
return $test<=$probability*$length;
}
例如,这将产生:
for($i=0; $i<10; $i++)
{
var_dump(checkWithProbability(1/3));
}
类似:
布尔(假)
布尔(真)
布尔(假)
布尔(假)
布尔(假)
布尔(假)
布尔(假)
布尔(假)
布尔(真)
布尔(假)
您可以使用该原理以期望的概率进行边缘检查:
function checkWithSet(array $set, $length=10000)
{
$left = 0;
foreach($set as $num=>$right)
{
$set[$num] = $left + $right*$length;
$left = $set[$num];
}
$test = mt_rand(1, $length);
$left = 1;
foreach($set as $num=>$right)
{
if($test>=$left && $test<=$right)
{
return $num;
}
$left = $right;
}
return null;//debug, no event realized
}
这个想法是使用geometry probability - 即将一些线部分分成具有相应长度的部分,然后检查我们的随机数属于哪个部分。
0.75 0.9
| |
五五
*--------*--*-----*-*--*--*
样本将是:
$set = [
1 => 0.4,
2 => 0.1,
3 => 0.25,
4 => 0.05,
5 => 0.1,
6 => 0.1
];
for($i=0; $i<10; $i++)
{
var_dump(checkWithSet($set));
}
结果如下:
整数(1)
整数(2)
整数(2)
整数(6)
整数(3)
整数(1)
整数(1)
整数(6)
整数(1)
整数(1)
您可以增加$length - 从理论上讲,这将提高随机检查的“质量”,但这并不是一件容易的事情 - 因为mt_rand() 使用伪随机生成器Mersenne Twister(在理想情况下不是真正的线性概率)