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 魔术函数使用说明
Feb 21 PHP
php动态实现表格跨行跨列实现代码
Nov 06 PHP
简单的cookie计数器实现源码
Jun 07 PHP
PHP设计模式之责任链模式的深入解析
Jun 13 PHP
使用PHP强制下载PDF文件示例
Jan 17 PHP
PHP中几个可以提高运行效率的代码写法、技巧分享
Aug 21 PHP
php采用curl模仿登录人人网发布动态的方法
Nov 07 PHP
基于PHP给大家讲解防刷票的一些技巧
Nov 18 PHP
PHP定时执行任务的3种方法详解
Dec 21 PHP
PHP MySql增删改查的简单实例
Jun 21 PHP
PHP简单预防sql注入的方法
Sep 27 PHP
通过PHP实现用户注册后邮箱验证激活
Nov 10 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连mysql和oracle数据库性能比较
2006/10/09 PHP
PHP IF ELSE简化/三元一次式的使用
2011/08/22 PHP
PHP7.1实现的AES与RSA加密操作示例
2018/06/15 PHP
PHP 对象接口简单实现方法示例
2020/04/13 PHP
JavaScript打开word文档的实现代码(c#)
2012/04/16 Javascript
JS去除字符串两端空格的简单实例
2013/12/27 Javascript
javascript将相对路径转绝对路径示例
2014/03/14 Javascript
jQuery实现文本框邮箱输入自动补全效果
2015/11/17 Javascript
jQuery手动点击实现图片轮播特效
2020/04/20 Javascript
原生JS取代一些JQuery方法的简单实现
2016/09/20 Javascript
浅谈jQuery中Ajax事件beforesend及各参数含义
2016/12/03 Javascript
assert()函数用法总结(推荐)
2017/01/25 Javascript
canvas实现图像放大镜
2017/02/06 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
2017/02/18 Javascript
利用 spin.js 生成等待效果(js 等待效果)
2017/06/25 Javascript
vue2.0 和 animate.css的结合使用
2017/12/12 Javascript
Node.js 使用jade模板引擎的示例
2018/05/11 Javascript
javascriptvoid(0)含义以及与&quot;#&quot;的区别讲解
2019/01/19 Javascript
详解使用React.memo()来优化函数组件的性能
2019/03/19 Javascript
javascript实现对话框功能警告(alert 消息对话框)确认(confirm 消息对话框)
2019/05/07 Javascript
JS sort方法基于数组对象属性值排序
2020/07/10 Javascript
js实现可爱的气泡特效
2020/09/05 Javascript
[00:59]DOTA2背景故事第二期之四大基本法则
2020/07/07 DOTA
[01:01]2020完美高校联赛(秋)西安落幕
2021/03/11 DOTA
Python中处理字符串之endswith()方法的使用简介
2015/05/18 Python
Python实现购物车功能的方法分析
2017/11/10 Python
Python实现的径向基(RBF)神经网络示例
2018/02/06 Python
python中import与from方法总结(推荐)
2019/03/21 Python
django框架自定义模板标签(template tag)操作示例
2019/06/24 Python
用pyqt5 给按钮设置图标和css样式的方法
2019/06/24 Python
Python3运算符常见用法分析
2020/02/14 Python
一些Unix笔试题和面试题
2013/01/22 面试题
家教广告词
2014/03/19 职场文书
马智宇结婚主持词
2014/04/01 职场文书
工作推荐信范文
2014/05/10 职场文书
材料物理专业求职信
2014/09/01 职场文书