PHP概率计算函数汇总
作者:hebedich 发布时间:2023-11-19 08:06:19
标签:PHP,概率计算
其实发这篇博感觉并没有什么用,太简单了,会的人不屑看,不会的人自已动动脑子也想到了。但是看着自已的博客已经这么久没更,真心疼~。粗略算下一篇只有代码的水文,会占用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']);
0
投稿
猜你喜欢
- # -*- coding: utf-8 -*-# @Author: CriseLYJ# @Date: 2020-08-14 12
- Javascript 中的闭包其实很改语言中很难理解的一部分。感谢 Stuart 提供了那么棒的 PPT,它深入浅出的解释了 Javascr
- 1. 准备工作有朋友可能没用过folium,它其实就是python的一个专业绘制地图的第三方库,所以在使用之前需要先安装它。pip 
- 之前写的单向链表和环形链表都只是单向的,只能单向遍历,不能根据后面的节点获取前面的节点,除非进行反转操作。双向链表每个节点都有两个指针,这两
- 01 ReplicaSet的架构 前面的文章中,我们说了ReplicaSet的基本概念和限制以及部署前的基本知识。
- 何为标准化:在数据分析之前,我们通常需要先将数据标准化(normalization),利用标准化后的数据进行数据分析。数据标准化也就是统计数
- 每个 batch 前清空梯度,否则会将不同 batch 的梯度累加在一块,导致模型参数错误。然后我们将输入和目标张量都移动到所需的设备上,并
- 以下函数采用FSO对象,文件位置在FSO.ASP。FSO对象的文件编码属性只有三种,系统默认,Unicode,ASCII,并没有我们要的ut
- 一、标准的数据集流程梳理分为几个步骤数据准备以及加载数据库–>数据加载器的调用或者设计–>
- 我就废话不多说了,大家还是直接看代码吧!import pymysqlimport pandas as pddef con_sql(db,sq
- 就像这个图的样子:解决方法,setting.py中DEBUG选项为True,否则无法映射到静态文件目录来源:https://blog.csd
- #覆盖覆盖:在继承关系中,子类实现了与基类同名的方法,在子类的实例调用该方法时,实例调用的是子类的覆盖版本。通俗的讲,就是小明继承了他⑧的自
- 1.使用Qt Design设计一个空白窗口(注意:我是使用MainWindow创建的窗口)2.使用PyUIC将.ui文件转换成.py文件右键
- 介绍reflect包实现运行时反射,允许一个程序操作任何类型的对象。典型的使用是:取静态类型interface{}的值,通过调用TypeOf
- 本文实例讲述了Python单元和文档测试。分享给大家供大家参考,具体如下:单元和文档测试1、单元测试单元测试就是用来对一个模块、一个函数或者
- 如果你的电脑内存较小那么想在本地做一些事情是很有局限性的(哭丧脸),比如想拿一个kaggle上面的竞赛来练练手,你会发现多数训练数据集都是大
- 分别创建增加、删除、更新的触发器(Trigger)来达到两张表之间数据同步的目的。 1:数据同步增加: 如有两张表——A表和B表,创建触发器
- 1从SQLServer导出数据 执行BCP: bcp "..." queryout "F:\test.txt&
- Cookie 模块,顾名思义,就是用来操作Cookie的模块。Cookie这块小蛋糕,玩过Web的人都知道,它是Server与Client保
- 安装MySQL,留作笔记,不知是否能够安装成功,试试吧。1、 进入mysql官网 地址<下载完毕,接下来就是安装了2、安装找到安装包,