生成具有修复概率的随机数

Ali*_*ani 5 php random probability

我在论坛中对此有很多不满,但所有答案都是如此具体的问题.我发现我最需要的是:Alon Gubkin的概率随机数发生器.

不同的是,Alon要求给予一张脸(这是六张)额外的机会.在我的情况下,我想划分六个面孔的机会,使它们加起来达到100%.例如,面部1有40%的几率,面部2只有10%,面部3有25%,......等.

我怎样才能做到这一点?

Alm*_* Do 8

具有线性概率的单概率检查可以通过以下方式轻松完成:

function checkWithProbability($probability=0.1, $length=10000)
{
   $test = mt_rand(1, $length);
   return $test<=$probability*$length;
}
Run Code Online (Sandbox Code Playgroud)

例如,这将产生:

for($i=0; $i<10; $i++)
{
   var_dump(checkWithProbability(1/3));
}
Run Code Online (Sandbox Code Playgroud)

就像是:

bool(false)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(true)
bool(false)

您可以使用该原则以期望的概率检查边缘:

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
}
Run Code Online (Sandbox Code Playgroud)

我们的想法是使用几何概率 - 即将一些线部分拆分成具有相应长度的部分,然后检查我们的随机数属于哪个部分.


                 0.75  0.9
                  |    |
                  V    V
*--------*--*-----*-*--*--* <-- (length)
^        ^  ^       ^     ^
|        |  |       |     |
0      0.4 0.5     0.8    1

样品将是:

$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));
}
Run Code Online (Sandbox Code Playgroud)

结果如:

int(1)
int(2)
int(2)
int(6)
int(3)
int(1)
int(1)
int(6)
int(1)
int(1)

你可以增加$length- 理论上,这将增加随机检查的"质量",但这不是太容易的事情 - 因为mt_rand()使用伪随机生成器,Mersenne Twister(在理想情况下,这不是真正的线性概率)