Heim  >  Artikel  >  Backend-Entwicklung  >  php 抽奖概率算法

php 抽奖概率算法

高洛峰
高洛峰Original
2016-11-22 10:37:431366Durchsuche

php 抽奖概率算法

/* 
 * 不同概率的抽奖原理就是把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[&#39;v&#39;]; 
    } 
    // 概率数组的总概率  
    $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(&#39;id&#39;=>1,&#39;name&#39;=>&#39;特等奖&#39;,&#39;v&#39;=>1),
    array(&#39;id&#39;=>2,&#39;name&#39;=>&#39;一等奖&#39;,&#39;v&#39;=>5),
    array(&#39;id&#39;=>3,&#39;name&#39;=>&#39;二等奖&#39;,&#39;v&#39;=>10),
    array(&#39;id&#39;=>4,&#39;name&#39;=>&#39;三等奖&#39;,&#39;v&#39;=>12),
    array(&#39;id&#39;=>5,&#39;name&#39;=>&#39;四等奖&#39;,&#39;v&#39;=>22),
    array(&#39;id&#39;=>6,&#39;name&#39;=>&#39;没中奖&#39;,&#39;v&#39;=>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() 更准确些......


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:php 进行 HTTP 认证Nächster Artikel:隐藏php脚本扩展名