Php 生成具有固定概率的随机数

Php 生成具有固定概率的随机数,php,random,probability,Php,Random,Probability,我在论坛上对此非常生气,但所有的答案都是针对所问问题的。我找到的最符合我需要的是: 不同的是,阿龙要求给一张脸(六张)额外的机会。在我的例子中,我想把这六张脸的机会分成几份,这样它们加起来就等于100%。例如,面1有40%的几率,面2只有10%,面3有25%。。。等等 我该怎么做 在您的情况下,您可能会生成从1到100的随机数,然后: if random in 1:40 -> face 1 elseif random in 41:50 -> face 2 and so on. 当

我在论坛上对此非常生气,但所有的答案都是针对所问问题的。我找到的最符合我需要的是:

不同的是,阿龙要求给一张脸(六张)额外的机会。在我的例子中,我想把这六张脸的机会分成几份,这样它们加起来就等于100%。例如,面1有40%的几率,面2只有10%,面3有25%。。。等等


我该怎么做

在您的情况下,您可能会生成从1到100的随机数,然后:

if random in 1:40 -> face 1
elseif random in 41:50 -> face 2
and so on. 

当然,要得到实数范围,实数代码会稍微复杂一些,而不是硬编码的ifs

我可以想出一个非常简单的解决方案。这一个不会改变随机数生成器的生成模式,但会解释结果,以适应上面的问题。我会让随机数生成器生成0到9之间的数字。然后执行以下映射,根据分配给该值的概率,我将生成的数字的范围分配给我的intrest值:

If result <= 3, face=1
else if result <=5, face =2
else is result <=25 face =3
//and so on

如果结果一个非常简单的方法是使用一个长度为100的数组,在其中写入“faces”数字,将其洗牌并获得第一个元素

因此,对于该数组中的示例,是40x110x225x3

小代码示例(未测试):

$probabilities=数组(
1 => 40,
2 => 10,
3 => 25,
4 => 5,
5 => 10,
6 => 10
);
$random=array();
foreach($key=>$value的概率){
对于($i=0;$i<$value;$i++){
$random[]=$key;
}
}
洗牌($随机);
echo$random[0];

线性概率的单一概率检查可以通过以下方法轻松完成:

function checkWithProbability($probability=0.1, $length=10000)
{
   $test = mt_rand(1, $length);
   return $test<=$probability*$length;
}
函数checkWithProbability($probability=0.1,$length=10000)
{
$test=mt_rand(1$length);
返回$test$right)
{
如果($test>=$left&&$test 0.1,
3 => 0.25,
4 => 0.05,
5 => 0.1,
6 => 0.1
];

对于($i=0;$i创建一个包含40个1、10个2、25个3的数组,然后选择一个随机项。可能的重复项会让我的朋友非常恼火。这就是我要找的。非常感谢^^。
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));
}
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
}
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));
}
int(1) int(2) int(2) int(6) int(3) int(1) int(1) int(6) int(1) int(1)