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 相关文章推荐
Windows下的PHP5.0安装配制详解
Sep 05 PHP
不用数据库的多用户文件自由上传投票系统(1)
Oct 09 PHP
PHP的开发框架的现状和展望
Mar 16 PHP
关于php连接mssql:pdo odbc sql server
Jul 20 PHP
PHP编码转换函数 自动转换字符集支持数组转换
Dec 16 PHP
将博客园(cnblogs.com)数据导入到wordpress的代码
Jan 06 PHP
国外十大最流行的PHP框架排名
Jul 04 PHP
php创建和删除目录函数介绍和递归删除目录函数分享
Nov 18 PHP
PHP中ajax无刷新上传图片与图片下载功能
Feb 21 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
Feb 23 PHP
php数据序列化测试实例详解
Aug 12 PHP
PHP实现正则表达式分组捕获操作示例
Feb 03 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去掉字符串的最后一个字符附substr()的用法
2011/03/23 PHP
php异常处理方法实例汇总
2015/06/24 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
PHP 模拟登陆功能实例详解
2019/09/10 PHP
jquery简单瀑布流实现原理及ie8下测试代码
2013/01/23 Javascript
javascript自定义的addClass()方法
2014/05/28 Javascript
jQuery实现Flash效果上下翻动的中英文导航菜单代码
2015/09/22 Javascript
js实现获取两个日期之间所有日期的方法
2016/06/17 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
jQuery实现验证码功能
2017/03/17 Javascript
Ionic3实现图片瀑布流布局
2017/08/09 Javascript
Angularjs cookie 操作实例详解
2017/09/27 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
JavaScript引用类型之基本包装类型实例分析【Boolean、Number和String】
2018/08/09 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
python写xml文件的操作实例
2014/10/05 Python
python实现简单日期工具类
2019/04/24 Python
Python单元测试工具doctest和unittest使用解析
2019/09/02 Python
Python中关于浮点数的冷知识
2019/09/22 Python
Linux系统下升级pip的完整步骤
2021/01/31 Python
AmazeUI 列表的实现示例
2020/08/17 HTML / CSS
世界上最大的汽车共享网站:Zipcar
2017/01/14 全球购物
红色康乃馨酒店:Red Carnation Hotels
2017/06/22 全球购物
西班牙在线药店:DosFarma
2020/03/28 全球购物
威盛公司软件C++工程师笔试题面试题
2012/07/16 面试题
团队精神演讲稿
2013/12/31 职场文书
班组长安全职责
2014/01/05 职场文书
银行先进个人事迹材料
2014/05/11 职场文书
小学模范班主任事迹材料
2014/05/13 职场文书
六一儿童节演讲稿
2014/05/23 职场文书
机械操作工岗位职责
2014/08/08 职场文书
代理人委托书
2014/09/16 职场文书
运动会加油稿50字
2015/07/21 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
解决mysql:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO/YES)
2021/06/26 MySQL
MySQL系列之二 多实例配置
2021/07/02 MySQL