根据加权百分比随机排列一组 URL

发布于 2024-11-30 10:36:50 字数 451 浏览 1 评论 0原文

我试图弄清楚如何根据百分比对 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 次。

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

I am trying to figure out how to shuffle an array of URL's based on a percentage so that each URL get's picked a certain number of times.

<?php

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

I thought about going the rand() route and just getting a random number between 1-100 and making a switch statement with a bunch of ranges, but that seems less than elegant and clumsy. I also don't know how reliable doing this would be. I am trying to get as close to perfect as possible. If I shuffle through 100 times I am not sure most of the rand() examples would list the above array with google.com and yahoo.com getting selected 25 times each (+/- 2) and bing.com getting selected 50 times.

Is their a way to get accurate weighted shuffling? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

江南月 2024-12-07 10:36:50

你仍然想要兰特。在 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;
    }
}

You'll still want a rand. In a distribution of 100, you're not likely to get a perfectly even 100% distribution. If you want that, you'll need to store state in a DB, or somehow static to the server itself. In fact, what you would do is just decrement the array values until they're all 0, then start again.

Here is a representation of how it would work without the perfect-match distribution (assuming it is in a function):

$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;
    }
}
乖乖兔^ω^ 2024-12-07 10:36:50

下面的逻辑怎么样?

  1. 对项目进行排序,使优先级较高的项目位于顶部
  2. 获取 1-100 之间的随机值
  3. 现在遍历列表并从随机值中减去项目的百分比,直到其变为负值。发生这种情况时,停止迭代列表并选择该项目作为所选项目

How about the following logic?

  1. Order items so that higher-priority ones are at the top
  2. Get a random value from 1-100
  3. Now go through the list and substract the item's percentage from the random value until it becomes negative. When this happens stop iterating over the list and choose the item as the selected one
雄赳赳气昂昂 2024-12-07 10:36:50

看起来你可以这样做:

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!

It looks like you could just do:

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

To get the value in front, just call key:

key( $myArr );

Or, you could just iterate through the whole thing: the array is in a randomized value:

foreach( $myArr as $key => $val ) 
   // todo: do Something!
假情假意假温柔 2024-12-07 10:36:50

试试这个

    <?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++;
    }   
    ?>

Try this

    <?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++;
    }   
    ?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文