zoukankan      html  css  js  c++  java
  • php 抽奖概率算法


    lottery.php

    
    <?php
    //转自https://segmentfault.com/a/1190000007431893
    /* 
     * 不同概率的抽奖原理就是把0到*(比重总数)的区间分块
     * 分块的依据是物品占整个的比重,再根据随机数种子来产生0-* 中的某个数
     * 判断这个数是落在哪个区间上,区间对应的就是抽到的那个物品。
     * 随机数理论上是概率均等的,那么相应的区间所含数的多少就体现了抽奖物品概率的不同。
     */
    function get_rand($proArr)
    {
        $result = array();
        foreach ($proArr as $key => $val) {
            $arr[$key] = $val['v'];
        }
        $proSum = array_sum($arr);      // 计算总权重
        $randNum = mt_rand(1, $proSum);
        $d1 = 0;
        $d2 = 0;
        for ($i=0; $i < count($arr); $i++) {
            $d2 += $arr[$i];
            if ($i==0) {
                $d1 = 0;
            } else {
                $d1 += $arr[$i-1];
            }
            if ($randNum >= $d1 && $randNum <= $d2) {
                $result = $proArr[$i];
            }
        }
        unset($arr);
        return $result;
    }
    
     /*
     * 使用较多的为这个方法
     */
    function get_rand1($proArr)
    {
        $result = array();
        foreach ($proArr as $key => $val) {
            $arr[$key] = $val['v'];
        }
        // 概率数组的总概率
        $proSum = array_sum($arr);
        asort($arr);
        // 概率数组循环
        foreach ($arr as $k => $v) {
            $randNum = mt_rand(1, $proSum);
            if ($randNum <= $v) {
                $result = $proArr[$k];
                break;
            } else {
                $proSum -= $v;
            }
        }
        return $result;
    }
    
    /*
     * 奖项数组 
     * 奖品id,名称,比重 
     */
    $arr = array(
        array('id'=>1,'name'=>'特等奖','v'=>1),
        array('id'=>2,'name'=>'一等奖','v'=>5),
        array('id'=>3,'name'=>'二等奖','v'=>10),
        array('id'=>4,'name'=>'三等奖','v'=>12),
        array('id'=>5,'name'=>'四等奖','v'=>22),
        array('id'=>6,'name'=>'没中奖','v'=>50)
    );
    
    //测试结果(10000次):
    get_rand():
    //count_1:0 count_2:490 count_3:1021 count_4:1172 count_5:2172 count_6:5145
    //特等奖中奖率全为:0
    get_rand1():
    //count_1:92 count_2:477 count_3:1017 count_4:1195 count_5:2264 count_6:4955
    //总体感觉 get_rand1() 更准确些......
    
    
  • 相关阅读:
    企业网络设计 华为S系列园区交换机组网
    zabbix安装注意以下几个部分
    grafana custom dashboard
    prometheus 生产环境部署
    Cephadm部署ceph octopus (15.2.13 )
    ipmi之外的新的选择redfish
    mongo & mongoexpress & redis & redisinsight 容器化安装
    ceph cluster 部署 (cephadm)
    kubernetes 1.21 helm3
    kubernetes 1.21部署 kubeprometheus
  • 原文地址:https://www.cnblogs.com/lovellll/p/10203035.html
Copyright © 2011-2022 走看看