基于概率的PHP数组随机项选取

基于概率的PHP数组随机项选取,php,Php,我有一张用户地图和他们为抽奖(或彩票或任何其他类似活动)购买的参赛作品/门票数量 用户到条目的映射结构如下所示: // Map the person to the amount of entries they have purchased $entries = [ 'Adam' => 5, 'James' => 3, 'Oliver' => 4, 'Holly' => 8 ]; 我想随机选择一个用户,但要根据票数考虑他们的机会。获胜概率必

我有一张用户地图和他们为抽奖(或彩票或任何其他类似活动)购买的参赛作品/门票数量

用户到条目的映射结构如下所示:

// Map the person to the amount of entries they have purchased
$entries = [
    'Adam' => 5,
    'James' => 3,
    'Oliver' => 4,
    'Holly' => 8
];
我想随机选择一个用户,但要根据票数考虑他们的机会。获胜概率必须为:

(用户票数/总票数)*100=概率百分比


例如,从测试阵列中,预期结果是Holly将在20次抽奖中赢得8次。

这是一个巧合,因为前几天我在为博彩网站编写脚本时创建了一个方法来实现这一点

请参阅注释,了解代码的组成部分:

// The array passed to the function should be your $entries array
function randProb(array $items) {
  $totalProbability = 0; // This is defined to keep track of the total amount of entries

  foreach ($items as $item => $probability) {
      $totalProbability += $probability;     
  }

  $stopAt = rand(0, $totalProbability); // This picks a random entry to select
  $currentProbability = 0; // The current entry count, when this reaches $stopAt the winner is chosen

  foreach ($items as $item => $probability) { // Go through each possible item
      $currentProbability += $probability; // Add the probability to our $currentProbability tracker
      if ($currentProbability >= $stopAt) { // When we reach the $stopAt variable, we have found our winner
          return $item;
      }
  }

  return null;
}

任何问题都可以在下面自由提问,如果您想输出中奖项目的值(概率),请在断点处返回
$probability
,而不是
$item

,这应该是您想要做的,并且非常容易理解

function rand_with_entries($entries) {

    //create a temporary array
    $tmp = [];

    //loop through all names
    foreach($entries as $name => $count) {

        //for each entry for a specific name, add name to `$tmp` array
        for ($x = 1; $x <= $count; $x++) {
            $tmp[] = $name;
        }

    }

    //return random name from `$tmp` array
    return $tmp[array_rand($tmp)];
}
函数rand_与_条目($entries){
//创建一个临时数组
$tmp=[];
//循环遍历所有名称
foreach($name=>$count形式的条目){
//对于特定名称的每个条目,将名称添加到“$tmp”数组中

对于($x=1;$xOk),您有以下数据:

$entries=[
“亚当”=>5,
“詹姆斯”=>3,
“奥利弗”=>4,
“霍莉”=>8
];
一种方法是根据此数据填充数组并使用
array\u rand
。以下是一个示例:

函数pickRand($array,$nb){
$newArray=[];
foreach($name=>$probability的数组){
$num=$probability;
而($num>0){
$newArray[]=$name;
$num--;
}
}
返回$newArray[array_rand($newArray,$nb)];
}
使用它:

$randomName=pickRand($entries,1);

你想要返回概率还是一个随机的名字?请发布你的一些代码/努力,然后只有我们可以帮助你。好的,就概率而言,你可以与所有人(5个亚当,3个詹姆斯,等等)建立一个数组吗然后只需使用array_rand?@grumpysaysrestatemonica随机name@MickaëlLeger我该怎么做?检查数组,然后将用户添加到一个新数组中,添加的次数与他们获得的条目的次数相同?当然,如果一个用户有数千条条目,并且他们的名称较长,这可能会导致性能问题?这很完美,我认为这会起作用。。.我不确定该把这段代码放在我文件的最上面吗?@AdamZorchubiez我很高兴我能这么做help@JoshWood这不可能是完全随机的,好像
$stopAt
是一个小数字,比如4,概率很低的用户是7,(假设其他用户高于7)如果他在列表中排名第一,他就可以赢得这个奖项。这类项目很重要,所以它不是随机的。你的
$nb
变量是什么?回报量是多少?@GrumpySaysRestatemonica是的,因为它是
数组中的一个参数,我认为最好在函数中使用它!希望不会有太多人购买太多门票。RAM会遭受损失ot@Cid我认为在许多环境中,在出现任何问题之前,您应该尽快达到允许的最大内存大小。我在多个具有300k+数组键的在线PHP测试仪上试用了它,它立即给出了名称。在我自己的个人服务器上,它也轻松地处理了300k。我会做更多,但会生成大量的
$entries
array开始在300k300k数字键或字符串键以上花费一些时间?检查@Cid Strings,我对键使用了
md5(rand())