【问题标题】:How to do random with priority? [duplicate]如何随机优先? [复制]
【发布时间】:2014-03-11 19:11:58
【问题描述】:

这是我的代码,例如:

<?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),
     );
?>

我希望系统在每次刷新时随机显示其中一个网址。我希望它比低优先级显示更高优先级的次数更多。我需要它用于横幅系统,优先级更高的支付更多,所以它们应该被更多地看到。

怎么做?

【问题讨论】:

    标签: php random


    【解决方案1】:

    您可以根据优先级将项目添加到数组中。如果一个项目的优先级为 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;
    }
    

    【讨论】:

      【解决方案2】:

      遍历所有横幅,并为每个横幅分配一个键(数字 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) ] ];
      

      【讨论】:

      • 你能给我一个例子吗? (使用顶部的数组)
      • 是的,这部分我明白了,但是如何创建所有的键呢?
      • 您可以创建一个格式为 $id => $url_id 的新数组。这里的 $url_id 将是原始数组中 url 的键(因此 google 将是 0,facebook 1 等)。并重复乘以优先级数(谷歌,脸书等两次......其余的一次)。
      • 所以你说我需要:使用foreach检查优先级并使用while将其添加到其他数组priority次,然后count()新数组并为她做随机?如果是这样,这是个好主意,除了我不知道如何添加到现有数组中的新“数组”(我不知道如何调用数组中的每个数组)......编辑:谢谢,Greate!
      • 正是这样!我给你写了一个小代码(未经测试,它来自我的头脑),看看它是否适合你。
      【解决方案3】:

      将新字段添加到数组中,命名为“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
      • 您在数组中添加了一个名为“prob”的新字段。所以第一个项目有 prob=2,第二个有 prob=4,第三个有 prob=6 等等。之后你得到一个从 1 到所有概率总和的随机数。之后,您正在寻找一个 prob 字段小于或等于从数组末尾开始的随机数的项目。例如,如果您 random 等于 5,则代码将返回第三项。
      【解决方案4】:

      有一个工作示例: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;
      

      【讨论】:

        【解决方案5】:
        $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)];
        

        【讨论】:

          【解决方案6】:
          $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 个横幅呢?
          • 你最后不需要else...谢谢你的想法,但数组只是一个例子。正如我所说,它是一个自动横幅系统,因此可能有 100 个网站,优先级最高为 10(目前优先级是按 Page Rank,但很快就会是其他方式)。
          • 对不起。我认为您可能想多了,而这个简单的解决方案就是您所需要的!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多