当前位置:首页 > PHP教程 > php应用 > 列表

php实现概率性随机抽奖代码

发布:smiling 来源: PHP粉丝网  添加日期:2021-07-03 22:01:17 浏览: 评论:0 

本文给大家分享的是使用php根据奖品的权重来实现概率性随机抽奖的代码,非常的使用,有类似需求的小伙伴,可以拿去参考下。

1、初始数据:

权重越大,抽取的几率越高

[奖品1, 权重 5], [ 奖品2, 权重6], [ 奖品3, 权重 7], [ 奖品4, 权重2]

2、处理步骤:

1)N = 5 + 6 + 7 + 2 = 20

2)然后取1-N的随机数M

3)界定各 奖品的权重范围值 奖品 1 : 1-5 ; 奖品2 : 6-11; 奖品3: 12-18; 奖品4: 19-20

4) 如果M在某个奖品的权重范围值内,标识这个奖品被抽取到

  1. <?php 
  2. /** 
  3.  * 奖品 
  4.  */ 
  5. class Prize { 
  6.   # ID 
  7.   public $id = null; 
  8.   # 权重 
  9.   public $weight = null; 
  10.   # 奖品名 
  11.   public $name = null; 
  12.    
  13.   # 权重范围区间起始值 
  14.   protected $start = 0; 
  15.   # 权重范围区间结束值 
  16.   protected $end = 0; 
  17.    
  18.   public function __construct($id$weight$name) { 
  19.     if (!$id) { 
  20.       throw new Exception('奖品ID为空.'); 
  21.     } 
  22.     $this->id = $id
  23.     $this->weight = $weight ? $weight : 0; 
  24.     $this->name = $name ? $name : '随机奖品' . $id
  25.   } 
  26.    
  27.   # id 
  28.   public function getId() { 
  29.     return $this->id; 
  30.   } 
  31.    
  32.   # 权重 
  33.   public function getWeight() { 
  34.     return $this->weight; 
  35.   } 
  36.    
  37.   # 设置权重范围区间 
  38.   public function setRange($start$end) { 
  39.     $this->start = $start
  40.     $this->end = $end
  41.   } 
  42.    
  43.   # 判断随机数是否在权重范围区间 
  44.   public function inRange($num) { 
  45.     return ($num >= $this->start) && ($num <= $this->end); 
  46.   } 
  47.    
  48. /** 
  49.  * 奖品池 
  50.  */ 
  51. class PrizePoll implements IteratorAggregate, Countable { 
  52.   # 奖品集 
  53.   protected $items = array(); 
  54.    
  55.   # 加入奖品 
  56.   public function addItem(Prize $item) { 
  57.     $this->items[$item->getId()] = $item
  58.     return $this
  59.   } 
  60.    
  61.   # 删除奖品 
  62.   public function removeItem($itemId) { 
  63.     if (isset($this->items[$itemId])) { 
  64.       unset($this->items[$itemId]); 
  65.     } 
  66.     return $this
  67.   } 
  68.    
  69.   # 更新奖品 
  70.   public function updateItem(Prize $item) { 
  71.     if (isset($this->items[$item->getId()])) { 
  72.       $this->items[$item->getId()] = $item
  73.     } 
  74.     return $this
  75.   } 
  76.    
  77.   # 获取所有奖品 
  78.   public function getItems() { 
  79.     return $this->items; 
  80.   } 
  81.    
  82.   # 所有所有可用奖品(如果权重为0,说明这个奖品永远不可能抽到) 
  83.   public function getVisibleItems() { 
  84.     $items = array(); 
  85.     foreach ($this->items as $item) { 
  86.       if ($item->getWeight()) { 
  87.         $items[$item->getId()] = $item
  88.       } 
  89.     } 
  90.     return $items
  91.   } 
  92.    
  93.   # Countable::count 
  94.   public function count() { 
  95.     return count($this->items); 
  96.   } 
  97.    
  98.   # IteratorAggregate::getIterator() 
  99.   public function getIterator() { 
  100.     return new ArrayIterator($this->items); 
  101.   } 
  102.    
  103. /** 
  104.  * 简单的抽奖类 
  105.  */ 
  106. class SimpleTurn { 
  107.   # 奖池 
  108.   protected $poll = null; 
  109.      
  110.   public function __construct(PrizePoll $poll) { 
  111.     if ($poll) { 
  112.       $this->setPoll($poll); 
  113.     } 
  114.   } 
  115.    
  116.   # 抽奖 
  117.   public function run(PrizePoll $poll) { 
  118.     $poll = $poll ? $poll : $this->poll; 
  119.     if ( ! $poll) { 
  120.       throw new Exception('奖池未初始化'); 
  121.     } 
  122.    
  123.     if ($poll->count() <= 0) { 
  124.       throw new Exception('奖池为空'); 
  125.     } 
  126.    
  127.     $items = $poll->getVisibleItems(); 
  128.     if (count($items) <= 0) { 
  129.       throw new Exception('奖池为空'); 
  130.     } 
  131.    
  132.     $sum = 0; 
  133.     foreach ($items as $item) { 
  134.       $start = $sum + 1; 
  135.       $sum += $item->getWeight(); 
  136.       $end = $sum
  137.    
  138.       # 设置奖品的权重范围区间 
  139.       $item->setRange($start$end); 
  140.     } 
  141.    
  142.     # 随机数 
  143.     $rand = $this->getRandNum(1, $sum); 
  144.    
  145.     # 区间段判断 
  146.     foreach ($items as $item) { 
  147.       if ($item->inRange($rand)) { 
  148.         return $item
  149.       } 
  150.     } 
  151.     return null; 
  152.   } 
  153.    
  154.   # 获取随机数 
  155.   public function getRandNum($min$max) { 
  156.     return mt_rand($min ? $min : 1, $max); 
  157.   } 
  158.    
  159.   # 设置奖池 
  160.   public function setPoll(PrizePoll $poll) { 
  161.     $this->poll = $poll
  162.   } 
  163.    
  164. # 示例 
  165. try { 
  166.   $prizePoll = new PrizePoll(); 
  167.   $prizePoll->addItem(new Prize(1, 5)) 
  168.     ->addItem(new Prize(2, 6)) 
  169.     ->addItem(new Prize(3, 7)) 
  170.     ->addItem(new Prize(4, 2)); 
  171.    
  172.   $turn = new SimpleTurn($prizePoll); 
  173.   $prize = $turn->run(); 
  174.   var_dump($prize); 
  175. } catch (Exception $e) { 
  176.   print_r($e); 
  177. }

Tags: php概率性随机抽奖

分享到: