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);
}