如何实现带优先级的随机算法?

3
这是我的代码,例如:
<?php
     $arr = array(
          array("url" => "http://google.com", "priority" => 2),
          array("url" => "http://facebook.com", "priority" => 2),
          array("url" => "http://youtube.com", "priority" => 2),
          array("url" => "http://stackoverflow.com", "priority" => 1),
          array("url" => "http://kickass.to", "priority" => 1),
          array("url" => "http://twitter.com", "priority" => 1),
          array("url" => "http://example.com", "priority" => 1),
     );
?>

我希望系统在每次刷新时随机显示其中一个URL。我希望它能优先显示更高优先级的URL,以此保证收益更高的广告更多地被展示。这是一个横幅系统,高优先级的广告付费更多,因此应该展示得更频繁。
如何实现?
6个回答

3

您可以根据优先级将项目添加到数组中。如果项目的优先级为2,则可以将其添加到数组中两次。然后,您可以从数组中随机取出一个项目。

// CREATE A NEW ARRAY TO HOLD ALL OF THE BANNERS
$banner_array = array();     

// LOOP THROUGH EACH ITEM IN THE ARRAY CURRENTLY HOLDING THE BANNERS
foreach ($arr AS $banner) {

    // FOR EACH NUMBER IN THE PRIORITY, ADD THE ITEM TO OUR NEW ARRAY
    // google.com, facebook.com, youtube.com WILL BE ADDED IN TWICE
    for ($i = 0; $i < $banner['priority']; $i++) {
        $banner_array[] = $banner['url'];
    }
}

// COUNT THE TOTAL NUMBER OF ITEMS IN OUR ARRAY
// WE WILL PICK OUT A NUMBER BETWEEN ZERO AND THIS NUMBER (MINUS 1)
$item_count = count($banner_array) - 1;

// ONCE WE HAVE A RANDOM NUMBER, WE CAN ACCESS THAT ITEM OF THE ARRAY
print "RANDOM URL: ".$banner_array[get_random_item($item_count)];


// THIS FUNCTION PICKS A NUMBER BETWEEN ZERO AND THE NUMBER OF ITEMS IN OUR ARRAY
function get_random_item($item_count) {
    mt_srand(microtime() * 1000000);
    $random_number = rand(0, $item_count);
    return $random_number;
}

1
遍历所有横幅,并为每个横幅分配一个键(数字ID)。 对于那些具有更高优先级的横幅,分配2个键(如果您希望具有更高优先级,则可以分配更多键)。 然后只需找到0(假设它是基于零的)和键的总数之间的随机数字。
rand(0, count($keys) - 1);

更新
这里有一些代码:
// $arr = Your original array

$keys = array();
for ($i = 0; $i < count($arr); $i++) { // you can also use foreach here
     for ($u = 0; $u < $arr[$i]['priority']; $u++) {
         $keys[] = $i;      
     }
}

然后,要获取一个随机的URL,但是带有优先级,请按照以下步骤进行:

$arr[ $keys[ rand(0, count($keys) - 1) ] ];

请问你能给我一个例子吗?(使用顶部的数组) - user3141603
是的,我理解了这部分内容,但是如何创建所有的键呢? - user3141603
你可以创建一个新的数组,格式为 $id => $url_id。这里的 $url_id 是原始数组中 URL 的键(例如 Google 是 0,Facebook 是 1 等)。然后根据优先级数字重复该过程(对于 Google、Facebook 等重复两次,对于其余的只重复一次)。 - Shomz
所以你的意思是我需要:使用foreach检查优先级,使用while将其添加到其他数组“priority”次,然后计算新数组的count()并为其进行随机操作?如果是这样,那么这是一个很好的想法,除了我不知道如何向现有数组添加新的“数组”(我不知道如何称呼数组中的每个元素)...编辑:谢谢,太棒了! - user3141603
没错!我写了一小段代码(未经测试,全是我脑海里想的),你可以看看它是否适用于你。 - Shomz

0
$prob = rand(0,9);
if($prob<2){
    //show google url
}else if($prob<4){
    //show facebook url
}else if($prob<6){
    //show youtube url
}else if($prob<7){
    //show stackoverflow url
}else if($prob<8){
    //show kickass url
}else if($prob<9){
    //show twitter url
}else{
    //show example url
}

太糟糕了。如果有200个横幅广告怎么办? - bountyh
你不需要在结尾加上else... 感谢你的想法,但是这个数组只是一个例子。正如我所说,这是一个自动横幅系统,可能有100个网站和优先级高达10(目前优先级是按页面排名,但很快会改变)。 - user3141603
抱歉。我觉得你可能想太多了,这个简单的解决方案就是你所需要的! - gtsouk

0
将一个名为“prob”的新字段添加到数组中,该字段包含元素显示的概率。
$prob = 0;
foreach($arr as $idx => $val) {
  $prob += $arr[$idx]["priority"];
  $arr[$idx]["prob"] = $prob; 
}

然后根据其优先级显示该项:

$p = rand(1, $prob);
for ($i=count($array)-1; $i>=0; $i--)
  if ($arr[$i]["prob"] <= $p) {
    // Show this item
    // ...
    break;
  }

我不明白它是如何工作的 :S - user3141603
您在数组中添加了一个名为“prob”的新字段。因此,第一项的prob为2,第二项的prob为4,第三项的prob为6等等。之后,您从1到所有概率的和中得到一个随机数。然后,您从数组末尾开始查找prob字段小于或等于随机数字的项目。例如,如果您的随机数等于5,则代码会返回第三个项目。 - Ivan Z

0

这里有一个可用的示例: http://3v4l.org/u5WNS

$arr = array(
      array("url" => "http://google.com", "priority" => 2),
      array("url" => "http://facebook.com", "priority" => 2),
      array("url" => "http://youtube.com", "priority" => 2),
      array("url" => "http://stackoverflow.com", "priority" => 1),
      array("url" => "http://kickass.to", "priority" => 1),
      array("url" => "http://twitter.com", "priority" => 1),
      array("url" => "http://example.com", "priority" => 1),
 );

// 重新创建另一个数组,其中包含相同值的多次出现(nb_of_occurence = priority)

$listOfUrl = array();
foreach ($arr as $url) {
    $nbOfOccurence = $url['priority'];

    for($i = 0 ; $i < $nbOfOccurence ; $i++) {
        $listOfUrl[] = $url['url'];
    }
} 

// 统计这个新数组中元素的数量

$nbOfElement = count($listOfUrl);

// 生成一个介于0和(元素数量-1)之间的随机索引

$randomIndex = rand(0,($nbOfElement - 1));

// 获取随机值

$randomURL = $listOfUrl[$randomIndex];

echo $randomURL;

0
$prob_arr = array();
$count=0;
foreach($arr as $key=>$val){
    for($j=0;$j<$val;$j++){
        $prob_arr[$i] = $key;
        $count++;
    }
}

$banner = prob_arr[rand(0,$count-1)];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接