PHP概率计算函数汇总


Posted in PHP onSeptember 13, 2015

其实发这篇博感觉并没有什么用,太简单了,会的人不屑看,不会的人自已动动脑子也想到了。但是看着自已的博客已经这么久没更,真心疼~。粗略算下一篇只有代码的水文,会占用OSC至少十几KB的数据库空间呢,但是,一想到乱弹里的然并卵,也就释然了。

<?php
 
/**
 * 概率计算类
 * 可用于抽奖等
 */
class Probability
{
  /**
   * 概率统计数据
   * thing => chance
   */
  var $data = array();
  var $chance_count = 0;
 
  function __construct($initdata = array()){
    if(!empty($initdata)){
      $this->data = $initdata;
      foreach($initdata as $d){
        $this->chance_count += $d['num'];
      }
    }
  }
 
  function addData($name, $chance){
    $this->data[]=array('name'=>$name, 'num'=>$chance);
    $this->chance_count += $chance;
  }
 
  function getOne(){
    $index = rand(0, $this->chance_count);
    foreach($this->data as $d){
      $index = $index-$d['num'];
      if($index<=0){
        return $d['name'];
      }
    }
    return '';
  }
}
 
 
/**
 * 使用示例
 */
$pro=new Probability();
$pro->addData('iphone',10);
$pro->addData('watch',30);
$pro->addData('$18',50);
$pro->addData('thank you',10);
$pro->addData('super big',1);
for($i=0;$i<100;$i++){
  echo $pro->getOne()."\n";
}

这是一个很经典的概率算法函数:

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

假设:我们有这样一个数组:a奖概率20%,b奖概率30%,c奖概率50%

$prize_arr =array('a'=>20,'b'=>30,'c'=>50);

模拟函数执行过程:

总概率精度为20+30+50=100

第一次数组循环,$procur=20

假设抽取的随机数rand(1,100),假设抽到$randNum=55

if判断-------

如果$randNum<=20,则result=a

否则进入下一循环,总概率精度变为100-20=80

第二次数组循环,$procur=30

假设抽取的随机数rand(1,80),假设抽到$randNum=33

if判断---------

如果$randNum<=30,则result=b

否则进入下一循环,总概率精度变为80-30=50

第三次数组循环,$prosur=50;

假设抽取的随机数rand(1,50),不管怎么抽,随机数都会<或=50,

那么得出result=c;

 因为样本没有改变,虽然可能抽取的随机数不止一个,但是概率是不变的。

或者也可以这样:

function get_rand($arr)
  {
    $pro_sum=array_sum($arr);
    $rand_num=mt_rand(1,$pro_sum);
    $tmp_num=0;
    foreach($arr as $k=>$val)
    {  
      if($rand_num<=$val+$tmp_num)
      {
        $n=$k;
        break;
      }else
      {
        $tmp_num+=$val;
      }
    }
    return $n;
  }

在给大家分享一个抽奖的概率算法

/*
 * 经典的概率算法,
 * $proArr是一个预先设置的数组,
 * 假设数组为:array(100,200,300,400),
 * 开始是从1,1000 这个概率范围内筛选第一个数是否在他的出现概率范围之内, 
 * 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,
 * 在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。
 * 这样 筛选到最终,总会有一个数满足要求。
 * 就相当于去一个箱子里摸东西,
 * 第一个不是,第二个不是,第三个还不是,那最后一个一定是。
 * 这个算法简单,而且效率非常 高,
 * 关键是这个算法已在我们以前的项目中有应用,尤其是大数据量的项目中效率非常棒。
 */
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;
}
 
 
/*
 * 奖项数组
 * 是一个二维数组,记录了所有本次抽奖的奖项信息,
 * 其中id表示中奖等级,prize表示奖品,v表示中奖概率。
 * 注意其中的v必须为整数,你可以将对应的 奖项的v设置成0,即意味着该奖项抽中的几率是0,
 * 数组中v的总和(基数),基数越大越能体现概率的准确性。
 * 本例中v的总和为100,那么平板电脑对应的 中奖概率就是1%,
 * 如果v的总和是10000,那中奖概率就是万分之一了。
 * 
 */
$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),
);
 
/*
 * 每次前端页面的请求,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;
print_r($res['yes']);
PHP 相关文章推荐
一步一步学习PHP(4) php 函数 补充2
Feb 15 PHP
php下使用SimpleXML 处理XML 文件
Feb 27 PHP
php数组对百万数据进行排除重复数据的实现代码
Jun 08 PHP
PHP zlib扩展实现页面GZIP压缩输出
Jun 17 PHP
php判断是否为json格式的方法
Mar 04 PHP
PHP内存缓存Memcached类实例
Dec 08 PHP
PHP学习笔记(三):数据类型转换与常量介绍
Apr 17 PHP
php强制用户转向www域名的方法
Jun 19 PHP
PHP使用array_merge重新排列数组下标的方法
Jul 22 PHP
利用PHP自动生成印有用户信息的名片
Aug 01 PHP
PHP的mysqli_rollback()函数讲解
Jan 23 PHP
laravel通用化的CURD的实现
Dec 13 PHP
整理php防注入和XSS攻击通用过滤
Sep 13 #PHP
教你识别简单的免查杀PHP后门
Sep 13 #PHP
php文件扩展名判断及获取文件扩展名的N种方法
Sep 12 #PHP
php上传功能集后缀名判断和随机命名(强力推荐)
Sep 10 #PHP
ubuntu下配置nginx+php+mysql详解
Sep 10 #PHP
ThinkPHP函数详解之M方法和R方法
Sep 10 #PHP
基于JQuery+PHP编写砸金蛋中奖程序
Sep 08 #PHP
You might like
php生成SessionID和图片校验码的思路和实现代码
2009/03/10 PHP
使用pthreads实现真正的PHP多线程(需PHP5.3以上版本)
2014/05/05 PHP
PHP中array_keys和array_unique函数源码的分析
2016/02/26 PHP
Zend Framework动作助手FlashMessenger用法详解
2016/03/05 PHP
说说掌握JavaScript语言的思想前提想学习js的朋友可以看看
2009/04/01 Javascript
JavaScript null和undefined区别分析
2009/10/14 Javascript
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
{}与function(){}选用空对象{}来存放keyValue
2012/05/23 Javascript
javascript动态加载三
2012/08/22 Javascript
JS文本框不能输入空格验证方法
2013/03/19 Javascript
javascript实现文字图片上下滚动的具体实例
2013/06/28 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
2014/11/28 Javascript
深入理解JavaScript系列(42):设计模式之原型模式详解
2015/03/04 Javascript
基于jQuery实现自动轮播旋转木马特效
2015/11/02 Javascript
实例讲解jquery与json的结合
2016/01/07 Javascript
原生javascript+css3编写的3D魔方动画旋扭特效
2016/03/14 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(二)
2017/01/21 Javascript
完美的js图片轮换效果
2017/02/05 Javascript
基于vue实现移动端圆形旋钮插件效果
2018/11/28 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
vue动态子组件的两种实现方式
2019/09/01 Javascript
js贪心算法 钱币找零问题代码实例
2019/09/11 Javascript
Vue封装全局过滤器Filters的步骤
2020/09/16 Javascript
使用Python编写简单的画图板程序的示例教程
2015/12/08 Python
Python下调用Linux的Shell命令的方法
2018/06/12 Python
Python3操作读写CSV文件使用包过程解析
2020/04/10 Python
python 利用opencv实现图像网络传输
2020/11/12 Python
华为菲律宾官方网站:HUAWEI Philippines
2021/02/23 全球购物
阳光体育活动总结
2014/04/30 职场文书
模特大赛策划方案
2014/05/28 职场文书
理财学专业自荐书
2014/06/28 职场文书
公司禁烟通知
2015/04/23 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
使用Python解决图表与画布的间距问题
2022/04/11 Python
Java设计模式中的命令模式
2022/04/28 Java/Android