首先来看一个经典的概率算法:
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;
}
这是昨天博主在一个聊天群里看到的,刚开始不太明白,网上一些帖子文章啥的就是写的一些不痛不痒的东西,没什么用处,这里博主就稍微的做一下讲解。
其实代码大家都能看懂,但是 if 判断的else那里很多人不明白为啥要用 $proSum - $proCur,这里这个算法呢,是用到了数学上的概率的算法,我们来举个例子,比如我有一个数组 $proArr = ['a'=>2,'b'=>3,'c'=>4,'d'=>1],a的概率是2/10,b的概率是3/10,c的概率是4/10,d的概率是1/10,
顺着程序走一遍,$proSum最开始是10,然后进入第一次循环,从1-10里面去随机数,然后判断是不是小于等于2,如果true就输出a,不等于$proSum-2,这时候$proSum就变成了8,然后再执行第二次循环,程序就是这么个流程。
第一次取的时候,$randNum是从10个数中取小于等于2的,概率就是2/10,第二次循环的时候,$randNum是从1-8中取小于等于3的,注意执行第二次循环的条件是第一次循环取的数是大于2的,是8/10,也就是说第二次循环取出小于等于3的概率是 8/10 * 3/(10-2) = 3/10,然后依次类推,这样第三次循环能取得小于等于4的概率就是 8/10 * (8-3)/(10-2) * 4/(10-2-3) = 4/10,第四次循环能取得小于等于1的概率就是 8/10 * (8-5)/(10-2) * (5-1)/(10-2-3) = 1/10。
数学上的概率算法大家懂了吗?