位置:首页 > PHP > 抽奖概率 >

PHP抽奖算法逻辑思维 代码如何实现 基础理论

字号+ 作者:micloud 来源:www.seoalphas.com 2019-01-09 08:18 浏览量:2372

抽奖在现实生活中是经常用到的一个功能,一些APP、大型网站更是一直都存在抽奖功能,兑换个积分、花积分兑换小礼品等等。如何设置好中奖概率,是抽奖功能中最重要的问题,就像近日平安银行APP抽奖事件一样,一个客户连续两次抽中iPhone x,但平安银行却不想兑现承诺了,平安承认你抽中了两部iPhone x,但是这是技术升级问题,我们不能兑换......这就略显尴尬了.....

言归正传,下面来说说用PHP实现抽奖的思路算法,这里先忽略前台效果,只说后台业务逻辑。

下面是示例代码,也是参考网上的代码分析一遍,具体说明在代码中都注释好了

<?php
/**
 * 中奖奖品数组
 * id 奖品id
 * name 奖品名称
 * chance 中奖的概率基数
 * 中奖概率为各个奖品中奖基数总和/单个奖品中奖基数
 * 也就是说,当chance中奖基数为0时,该奖品就不可能抽中了
 * **/
$prizeArr = array(
    0=>array( 'id'=>1,'name'=>'一千万毛爷爷','chance'=>1 ),
    1=>array( 'id'=>2,'name'=>'iPhone XS Max','chance'=>5 ),
    2=>array( 'id'=>3,'name'=>'电磁炉','chance'=>10 ),
    3=>array( 'id'=>4,'name'=>'电饭煲','chance'=>30 ),
    4=>array( 'id'=>5,'name'=>'10元话费','chance'=>54 ),
    5=>array( 'id'=>6,'name'=>'现金1元','chance'=>100 )
);
/**
 * 对数组进行处理
 * 主要是方便后期数据的处理
 * 筛选出id 和 chance两个数值项组成管理数组
 **/
foreach( $prizeArr as $k => $v ){
    //使用新数组item
    $items[$v['id']] = $v['chance'];
}
/**
 * 新数组输出结果如下:
 * 分别对应原数组的id 和 chance
 *
array(6) {
    [1]=>int(1)
    [2]=>int(5)
    [3]=>int(10)
    [4]=>int(30)
    [5]=>int(54)
    [6]=>int(100)
}
 */
//var_dump(array_sum($items)); //对数组中所有值求和 上面处理新数组就是为了计算基数和
/**
 * @param $items 奖品数组
 * @return int|string 中奖奖品ID
 */
function get_rand($items){
    $num = array_sum($items);    //计算出基数200 基数越大 中间概率相对越小
    foreach( $items as $k => $chance ){
        $rand = mt_rand(1, $num);//概率区间(整数) 从1~200中间取整数
        if( $rand <= $chance ){
   /**  概率随机数   奖品中奖基数   如果随机数大于100 必然不中奖,此种情况只需设置好**/
            $result = $k;
            echo '中奖的:--随机数'.$rand.'--基数'.$chance.'';
            break;              //如果中奖 直接终止本次循环 本次抽奖结束
        }else{
            /**
             *如果未中奖,基数和减去本次的奖品基数
             * 相当于下次循环时,中奖概率加大
             * 但是由于奖品数组都是id从低到高开始进行的,必然是先减去最大奖的基数
             * 当一轮循环下来都未中奖时,基数和已减到和奖品基数最大的相同,这样中奖的就是我们设置的最大基数的奖品
             */
            $num-=$chance;  //等效于$num = $num - $chance;
            echo '*未中奖的随机数'.$rand.'*'."&ensp;"."&ensp;"."&ensp;";
        }
    }
    return $result;
}
$res = get_rand($items);
$prize = $prizeArr[$res-1]['name'];
echo '-----抽中的奖品名称'.$prize;


运行下看看效果:

抽奖代码运行结果截图

抽奖代码运行结果截图

抽奖代码运行结果截图

抽奖代码运行结果截图

抽奖代码运行结果截图

之所以说上面算法有弊端,是因为抽中大奖的概率还是有的,当然提高奖品中奖基数可以把中大奖概率降下去,但是最后中奖的随机参数还是要依靠PHP语法mt_rand()函数生成的随机数,除非设置不中奖,否则的话就有可能还没抽几次就出现大大大奖了。

这种可以人工进行干预,开始的时候把大奖中奖基数都设置为0,不可中奖,待到时间到了,再放出。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • PHP抽奖算法完善 增大基数 减小大奖中奖概率

    PHP抽奖算法完善 增大基数 减小大奖中奖概率

    浏览次数:2122

网友点评
评论区域