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在某个奖品的权重范围值内,标识这个奖品被抽取到
<?php /** *奖品 */ classPrize{ #ID public$id=null; #权重 public$weight=null; #奖品名 public$name=null; #权重范围区间起始值 protected$start=0; #权重范围区间结束值 protected$end=0; publicfunction__construct($id,$weight,$name){ if(!$id){ thrownewException('奖品ID为空.'); } $this->id=$id; $this->weight=$weight?$weight:0; $this->name=$name?$name:'随机奖品'.$id; } #id publicfunctiongetId(){ return$this->id; } #权重 publicfunctiongetWeight(){ return$this->weight; } #设置权重范围区间 publicfunctionsetRange($start,$end){ $this->start=$start; $this->end=$end; } #判断随机数是否在权重范围区间 publicfunctioninRange($num){ return($num>=$this->start)&&($num<=$this->end); } } /** *奖品池 */ classPrizePollimplementsIteratorAggregate,Countable{ #奖品集 protected$items=array(); #加入奖品 publicfunctionaddItem(Prize$item){ $this->items[$item->getId()]=$item; return$this; } #删除奖品 publicfunctionremoveItem($itemId){ if(isset($this->items[$itemId])){ unset($this->items[$itemId]); } return$this; } #更新奖品 publicfunctionupdateItem(Prize$item){ if(isset($this->items[$item->getId()])){ $this->items[$item->getId()]=$item; } return$this; } #获取所有奖品 publicfunctiongetItems(){ return$this->items; } #所有所有可用奖品(如果权重为0,说明这个奖品永远不可能抽到) publicfunctiongetVisibleItems(){ $items=array(); foreach($this->itemsas$item){ if($item->getWeight()){ $items[$item->getId()]=$item; } } return$items; } #Countable::count publicfunctioncount(){ returncount($this->items); } #IteratorAggregate::getIterator() publicfunctiongetIterator(){ returnnewArrayIterator($this->items); } } /** *简单的抽奖类 */ classSimpleTurn{ #奖池 protected$poll=null; publicfunction__construct(PrizePoll$poll){ if($poll){ $this->setPoll($poll); } } #抽奖 publicfunctionrun(PrizePoll$poll){ $poll=$poll?$poll:$this->poll; if(!$poll){ thrownewException('奖池未初始化'); } if($poll->count()<=0){ thrownewException('奖池为空'); } $items=$poll->getVisibleItems(); if(count($items)<=0){ thrownewException('奖池为空'); } $sum=0; foreach($itemsas$item){ $start=$sum+1; $sum+=$item->getWeight(); $end=$sum; #设置奖品的权重范围区间 $item->setRange($start,$end); } #随机数 $rand=$this->getRandNum(1,$sum); #区间段判断 foreach($itemsas$item){ if($item->inRange($rand)){ return$item; } } returnnull; } #获取随机数 publicfunctiongetRandNum($min,$max){ returnmt_rand($min?$min:1,$max); } #设置奖池 publicfunctionsetPoll(PrizePoll$poll){ $this->poll=$poll; } } #示例 try{ $prizePoll=newPrizePoll(); $prizePoll->addItem(newPrize(1,5)) ->addItem(newPrize(2,6)) ->addItem(newPrize(3,7)) ->addItem(newPrize(4,2)); $turn=newSimpleTurn($prizePoll); $prize=$turn->run(); var_dump($prize); }catch(Exception$e){ print_r($e); }