1

我试图弄清楚如何根据百分比对 URL 数组进行洗牌,以便每个 URL 都被选中一定次数。

<?php

  $urls = array(
  'http://www.google.com'=>'25%', 
  'http://www.yahoo.com'=>'25%',
  'http://www.bing.com' =>'50%');

我想过走 rand() 路线,只得到一个 1-100 之间的随机数,然后用一堆范围做一个 switch 语句,但这似乎不够优雅和笨拙。我也不知道这样做有多可靠。我试图尽可能接近完美。如果我随机播放 100 次,我不确定大多数 rand() 示例是否会列出上面的数组,其中 google.com 和 yahoo.com 分别被选中 25 次 (+/- 2) 和 bing.com 被选中 50 次。

他们是一种获得准确加权改组的方法吗?谢谢

4

4 答案 4

1

下面的逻辑呢?

  1. 对项目进行排序,以便优先级较高的项目位于顶部
  2. 获取 1-100 的随机值
  3. 现在遍历列表并从随机值中减去项目的百分比,直到它变为负数。发生这种情况时停止迭代列表并选择该项目作为选定的项目
于 2011-08-20T06:32:43.637 回答
1

看起来你可以这样做:

usort( $myArr, function( $a, $b ) {
   return str_replace( "%", "", $a )/rand(1,100) - 
          str_replace( "%", "", $b )/rand(1,100);
} );

要获得前面的值,只需调用key

key( $myArr );

或者,您可以遍历整个内容:数组是一个随机值:

foreach( $myArr as $key => $val ) 
   // todo: do Something!
于 2011-08-20T06:38:05.483 回答
1

你仍然想要一个兰特。在 100 的分布中,您不可能得到完美均匀的 100% 分布。如果需要,您需要将状态存储在数据库中,或者以某种方式静态存储到服务器本身。实际上,您要做的只是将数组值递减,直到它们全部为 0,然后重新开始。

这是在没有完美匹配分布的情况下如何工作的表示(假设它在函数中):

$urls = array(
  'http://www.google.com'=>25, 
  'http://www.yahoo.com'=>25,
  'http://www.bing.com' =>50);

// Assuming that totalWeight might not be 100 for some reason.
$totalWeight = array_sum(array_values($urls)); 

$currentWeight = 0;
$rand = rand(1,$totalWeight);

foreach ($urls as $key=>$value)
{
    $currentWeight += $value;
    if ($currentWeight > $rand)
    {
        return $key;
    }
}
于 2011-08-20T06:38:40.627 回答
0

试试这个

    <?php
    $urls = array(
    'http://www.google.com'=>25, 
    'http://www.yahoo.com'=>25,
    'http://www.bing.com' =>50);

    $count = 1;
    $random = rand(0, 100);

    foreach($urls as $url => $range) {
       if($random > ($range * ($count - 1)) && $random < ($range * ($count + 1)))
           return $url;
       $count++;
    }   
    ?>
于 2011-08-20T06:37:42.980 回答