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


Posted in PHP onJanuary 02, 2016

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
/**
 * 奖品
 */
class Prize {
  # ID
  public $id = null;
  # 权重
  public $weight = null;
  # 奖品名
  public $name = null;
 
  # 权重范围区间起始值
  protected $start = 0;
  # 权重范围区间结束值
  protected $end = 0;
 
  public function __construct($id, $weight, $name) {
    if (!$id) {
      throw new Exception('奖品ID为空.');
    }
    $this->id = $id;
    $this->weight = $weight ? $weight : 0;
    $this->name = $name ? $name : '随机奖品' . $id;
  }
 
  # id
  public function getId() {
    return $this->id;
  }
 
  # 权重
  public function getWeight() {
    return $this->weight;
  }
 
  # 设置权重范围区间
  public function setRange($start, $end) {
    $this->start = $start;
    $this->end = $end;
  }
 
  # 判断随机数是否在权重范围区间
  public function inRange($num) {
    return ($num >= $this->start) && ($num <= $this->end);
  }
}
 
/**
 * 奖品池
 */
class PrizePoll implements IteratorAggregate, Countable {
  # 奖品集
  protected $items = array();
 
  # 加入奖品
  public function addItem(Prize $item) {
    $this->items[$item->getId()] = $item;
    return $this;
  }
 
  # 删除奖品
  public function removeItem($itemId) {
    if (isset($this->items[$itemId])) {
      unset($this->items[$itemId]);
    }
    return $this;
  }
 
  # 更新奖品
  public function updateItem(Prize $item) {
    if (isset($this->items[$item->getId()])) {
      $this->items[$item->getId()] = $item;
    }
    return $this;
  }
 
  # 获取所有奖品
  public function getItems() {
    return $this->items;
  }
 
  # 所有所有可用奖品(如果权重为0,说明这个奖品永远不可能抽到)
  public function getVisibleItems() {
    $items = array();
    foreach ($this->items as $item) {
      if ($item->getWeight()) {
        $items[$item->getId()] = $item;
      }
    }
    return $items;
  }
 
  # Countable::count
  public function count() {
    return count($this->items);
  }
 
  # IteratorAggregate::getIterator()
  public function getIterator() {
    return new ArrayIterator($this->items);
  }
}
 
/**
 * 简单的抽奖类
 */
class SimpleTurn {
  # 奖池
  protected $poll = null;
   
  public function __construct(PrizePoll $poll) {
    if ($poll) {
      $this->setPoll($poll);
    }
  }
 
  # 抽奖
  public function run(PrizePoll $poll) {
    $poll = $poll ? $poll : $this->poll;
    if ( ! $poll) {
      throw new Exception('奖池未初始化');
    }
 
    if ($poll->count() <= 0) {
      throw new Exception('奖池为空');
    }
 
    $items = $poll->getVisibleItems();
    if (count($items) <= 0) {
      throw new Exception('奖池为空');
    }
 
    $sum = 0;
    foreach ($items as $item) {
      $start = $sum + 1;
      $sum += $item->getWeight();
      $end = $sum;
 
      # 设置奖品的权重范围区间
      $item->setRange($start, $end);
    }
 
    # 随机数
    $rand = $this->getRandNum(1, $sum);
 
    # 区间段判断
    foreach ($items as $item) {
      if ($item->inRange($rand)) {
        return $item;
      }
    }
    return null;
  }
 
  # 获取随机数
  public function getRandNum($min, $max) {
    return mt_rand($min ? $min : 1, $max);
  }
 
  # 设置奖池
  public function setPoll(PrizePoll $poll) {
    $this->poll = $poll;
  }
}
 
# 示例
try {
  $prizePoll = new PrizePoll();
  $prizePoll->addItem(new Prize(1, 5))
    ->addItem(new Prize(2, 6))
    ->addItem(new Prize(3, 7))
    ->addItem(new Prize(4, 2));
 
  $turn = new SimpleTurn($prizePoll);
  $prize = $turn->run();
  var_dump($prize);
} catch (Exception $e) {
  print_r($e);
}
PHP 相关文章推荐
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
Sep 24 PHP
php 显示指定路径下的图片
Oct 29 PHP
thinkphp的c方法使用示例
Feb 24 PHP
PHP调用JAVA的WebService简单实例
Mar 11 PHP
PHP实现Soap通讯的方法
Nov 03 PHP
thinkphp3.x中display方法及show方法的用法实例
May 19 PHP
PHP实现批量检测网站是否能够正常打开的方法
Aug 23 PHP
PHP实现随机生成水印图片功能
Mar 22 PHP
PHP 断点续传实例详解
Nov 11 PHP
PHP开发之用微信远程遥控服务器
Jan 25 PHP
PHP判断是否微信访问的方法示例
Mar 27 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 PHP
php实现给一张图片加上水印效果
Jan 02 #PHP
前端必学之PHP语法基础
Jan 01 #PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
Dec 31 #PHP
WordPress中获取指定分类及其子分类下的文章数目
Dec 31 #PHP
Swoole-1.7.22 版本已发布,修复PHP7相关问题
Dec 31 #PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
Dec 31 #PHP
简单了解将WordPress中的工具栏移到底部的小技巧
Dec 31 #PHP
You might like
PHP 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
2013/06/20 PHP
php线性表的入栈与出栈实例分析
2015/06/12 PHP
php简单的上传类分享
2016/05/15 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
利用jquery操作select下拉列表框的代码
2010/06/04 Javascript
Jquery动态进行图片缩略的原理及实现
2013/08/13 Javascript
前端必备神器 Snap.svg 弹动效果
2014/11/10 Javascript
js 自带的sort() 方法全面了解
2016/08/16 Javascript
详解AngularJs路由之Ui-router-resolve(预加载)
2017/06/13 Javascript
浅谈angular4 ng-content 中隐藏的内容
2017/08/18 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
2018/03/08 Javascript
小程序实现带年月选取效果的日历
2018/06/27 Javascript
微信小程序项目实践之主页tab选项实现
2018/07/18 Javascript
centos系统升级python 2.7.3
2014/07/03 Python
Python实现矩阵加法和乘法的方法分析
2017/12/19 Python
Django中的ajax请求
2018/10/19 Python
Python3爬虫爬取百姓网列表并保存为json功能示例【基于request、lxml和json模块】
2018/12/05 Python
Python assert语句的简单使用示例
2019/07/28 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
Python测试Kafka集群(pykafka)实例
2019/12/23 Python
Python高阶函数、常用内置函数用法实例分析
2019/12/26 Python
Python表达式的优先级详解
2020/02/18 Python
python使用Geany编辑器配置方法
2020/02/21 Python
python新式类和经典类的区别实例分析
2020/03/23 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
2020/05/25 Python
通过实例简单了解Python sys.argv[]使用方法
2020/08/04 Python
pytorch 计算Parameter和FLOP的操作
2021/03/04 Python
Farfetch澳大利亚官网:Farfetch Australia
2020/04/26 全球购物
jQuery treeview树形结构应用
2021/03/24 jQuery
投标授权委托书范文
2014/08/02 职场文书
股指期货心得体会
2014/09/13 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
个人融资协议书范本两则
2014/10/15 职场文书
2015年六一儿童节演讲稿
2015/03/19 职场文书
python井字棋游戏实现人机对战
2022/04/28 Python