php编写的抽奖程序中奖概率算法


Posted in PHP onMay 14, 2015

们先完成后台PHP的流程,PHP的主要工作是负责配置奖项及对应的中奖概率,当前端页面点击翻动某个方块时会想后台PHP发送ajax请求,那么后台PHP根据配置的概率,通过概率算法给出中奖结果,同时将未中奖的奖项信息一并以JSON数据格式发送给前端页面。

先来看概率计算函数

function get_rand($proArr) { 
  $result = ''; 
 
  //概率数组的总概率精度 
  $proSum = array_sum($proArr); 
 
  //概率数组循环 
  foreach ($proArr as $key => $proCur) { 
    $randNum = mt_rand(1, $proSum); 
    if ($randNum <= $proCur) { 
      $result = $key; 
      break; 
    } else { 
      $proSum -= $proCur; 
    } 
  } 
  unset ($proArr); 
 
  return $result; 
}

上述代码是一段经典的概率算法,$proArr是一个预先设置的数组,假设数组为:array(100,200,300,400),开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内, 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。这样筛选到最终,总会有一个数满足要求。就相当于去一个箱子里摸东西,第一个不是,第二个不是,第三个还不是,那最后一个一定是。这个算法简单,而且效率非常高,关键是这个算法已在我们以前的项目中有应用,尤其是大数据量的项目中效率非常棒。

接下来我们通过PHP配置奖项。

$prize_arr = array( 
  '0' => array('id'=>1,'prize'=>'平板电脑','v'=>1), 
  '1' => array('id'=>2,'prize'=>'数码相机','v'=>5), 
  '2' => array('id'=>3,'prize'=>'音箱设备','v'=>10), 
  '3' => array('id'=>4,'prize'=>'4G优盘','v'=>12), 
  '4' => array('id'=>5,'prize'=>'10Q币','v'=>22), 
  '5' => array('id'=>6,'prize'=>'下次没准就能中哦','v'=>50), 
);

该二维数组,记录了所有本次抽奖的奖项信息,其中id表示中奖等级,prize表示奖品,v表示中奖概率。注意其中的v必须为整数,你可以将对应的奖项的v设置成0,即意味着该奖项抽中的几率是0,数组中v的总和(基数),基数越大越能体现概率的准确性。本例中v的总和为100,那么平板电脑对应的中奖概率就是1%,如果v的总和是10000,那中奖概率就是万分之一了。

每次前端页面的请求,PHP循环奖项设置数组,通过概率计算函数get_rand获取抽中的奖项id。将中奖奖品保存在数组$res['yes']中,而剩下的未中奖的信息保存在$res['no']中,最后输出json个数数据给前端页面。

foreach ($prize_arr as $key => $val) { 
   $arr[$val['id']] = $val['v']; 
 } 
 
 $rid = get_rand($arr); //根据概率获取奖项id 
 
 $res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项 
 unset($prize_arr[$rid-1]); //将中奖项从数组中剔除,剩下未中奖项 
 shuffle($prize_arr); //打乱数组顺序 
 for($i=0;$i<count($prize_arr);$i++){ 
   $pr[] = $prize_arr[$i]['prize']; 
 } 
 $res['no'] = $pr; 
 echo json_encode($res);

另附上一个网友的实现方法

/**
  * 抽奖
  * @param int $total
  */
  function getReward($total=1000)
  {
  $win1 = floor((0.12*$total)/100);
  $win2 = floor((3*$total)/100);
  $win3 = floor((12*$total)/100);
  $other = $total-$win1-$win2-$win3;
  $return = array();
  for ($i=0;$i<$win1;$i++)
  {
  $return[] = 1;
  }
  for ($j=0;$j<$win2;$j++)
  {
  $return[] = 2;
  }
  for ($m=0;$m<$win3;$m++)
  {
  $return[] = 3;
  }
  for ($n=0;$n<$other;$n++)
  {
  $return[] = '谢谢惠顾';
  }
  shuffle($return);
  return $return[array_rand($return)];
  }
  $data = getReward();
  echo $data;
  ?>

以上所述就是本文的全部内容了,希望大家能够喜欢。

PHP 相关文章推荐
那些年一起学习的PHP(三)
Mar 22 PHP
PHP连接SQLServer2005方法及代码
Dec 26 PHP
PHP超牛逼无限极分类生成树方法
May 11 PHP
php自动给网址加上链接的方法
Jun 02 PHP
PHP使用内置函数file_put_contents写入文件及追加内容的方法
Dec 07 PHP
thinkPHP中分页用法实例分析
Dec 26 PHP
wordpress网站转移到本地运行测试的方法
Mar 15 PHP
基于Laravel5.4实现多字段登录功能方法示例
Aug 11 PHP
PHP数据库编程之MySQL优化策略概述
Aug 16 PHP
浅析PHP类的反射来实现依赖注入过程
Feb 06 PHP
thinkPHP框架动态配置用法实例分析
Jun 14 PHP
php输出形式实例整理
May 05 PHP
深入浅出php socket编程
May 13 #PHP
PHP中的traits简单使用实例
May 13 #PHP
PHP中的traits实现代码复用使用实例
May 13 #PHP
浅谈本地WAMP环境的搭建
May 13 #PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
May 13 #PHP
简单解决新浪SAE无法上传文件的问题
May 13 #PHP
PHP file_get_contents函数读取远程数据超时的解决方法
May 13 #PHP
You might like
如何使用PHP中的字符串函数
2006/10/09 PHP
php上的memcache和memcached两个pecl库
2010/03/29 PHP
php防攻击代码升级版
2010/12/29 PHP
PHP时间戳与日期之间转换的实例介绍
2013/04/19 PHP
PHP is_array() 检测变量是否是数组的实现方法
2016/06/13 PHP
PHP实现的各类hash算法长度及性能测试实例
2017/08/27 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
Windows Live的@live.com域名注册漏洞 利用代码
2006/12/27 Javascript
js中的异常处理try...catch使用介绍
2013/09/21 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
2013/10/29 Javascript
Nodejs实现多人同时在线移动鼠标的小游戏分享
2014/12/06 NodeJs
javascript实现延时显示提示框特效代码
2016/04/27 Javascript
js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】
2016/08/02 Javascript
jQuery加载及解析XML文件的方法实例分析
2017/01/22 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
2018/03/21 Javascript
js动态引入的四种方法
2018/05/05 Javascript
vue通过指令(directives)实现点击空白处收起下拉框
2018/12/06 Javascript
js时间戳转yyyy-MM-dd HH-mm-ss工具类详解
2019/04/30 Javascript
layui 监听select选择 获取当前select的ID名称方法
2019/09/24 Javascript
vue中提示$index is not defined错误的解决方式
2020/09/02 Javascript
[52:02]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第一场 11.27
2020/11/30 DOTA
python之wxPython菜单使用详解
2014/09/28 Python
Python实现string字符串连接的方法总结【8种方式】
2018/07/06 Python
python用plt画图时,cmp设置方法
2018/12/13 Python
Python 分发包中添加额外文件的方法
2019/08/16 Python
Python实现Restful API的例子
2019/08/31 Python
详解Python time库的使用
2019/10/10 Python
Python使用graphviz画流程图过程解析
2020/03/31 Python
通过实例简单了解python yield使用方法
2020/08/06 Python
The North Face北面法国官网:美国著名户外品牌
2019/11/01 全球购物
2015公务员年度考核评语
2015/03/25 职场文书
中标通知书范本
2015/04/17 职场文书
党员干部公开承诺书范文
2015/04/27 职场文书
广播体操比赛主持词
2015/06/29 职场文书
golang 如何通过反射创建新对象
2021/04/28 Golang