PHP幾個經常使用的機率算法

算法一

 1 /**  2  * 全機率計算  3  *  4  * @param array $p array('a'=>0.5,'b'=>0.2,'c'=>0.4)  5  * @return string 返回上面數組的key  6  */
 7 function random($ps){  8     static $arr = array();  9     $key = md5(serialize($ps)); 10     if (!isset($arr[$key])) { 11         $max = array_sum($ps); 12         foreach ($ps as $k=>$v) { 13             $v = $v / $max * 10000; 14             for ($i=0; $i<$v; $i++) $arr[$key][] = $k; 15  } 16  } 17     return $arr[$key][mt_rand(0,count($arr[$key])-1)]; 18 }

 

算法二

 1 function get_rand($proArr) {  2     $result = '';  3     //機率數組的總機率精度
 4     $proSum = array_sum($proArr);  5     //機率數組循環
 6     foreach ($proArr as $key => $proCur) {  7         $randNum = mt_rand(1, $proSum);  8         if ($randNum <= $proCur) {  9             $result = $key; 10             break; 11         } else { 12             $proSum -= $proCur; 13  } 14  } 15     unset ($proArr); 16     return $result; 17 }

 

算法二是一段經典的機率算法,$proArr是一個預先設置的數組,假設數組爲:array(100,200,300,400),開始是從1,1000這個機率範圍內篩選第一個數是否在他的出現機率範圍以內, 若是不在,則將機率空減,也就是k的值減去剛剛的那個數字的機率空間,在本例當中就是減去100,也就是說第二個數是在1,900這個範圍內篩選的。這樣篩選到最終,總會有一個數知足要求。就至關於去一個箱子裏摸東西,第一個不是,第二個不是,第三個還不是,那最後一個必定是。這個算法簡單,並且效率很是高,關鍵是這個算法已在咱們之前的項目中有應用,尤爲是大數據量的項目中效率很是棒。前端

接下來咱們經過PHP配置獎項。算法

1 $prize_arr = array( 2     '0' => array('id'=>1,'prize'=>'平板電腦','v'=>1),
3     '1' => array('id'=>2,'prize'=>'數碼相機','v'=>5),
4     '2' => array('id'=>3,'prize'=>'音箱設備','v'=>10),
5     '3' => array('id'=>4,'prize'=>'4G優盤','v'=>12),
6     '4' => array('id'=>5,'prize'=>'10Q幣','v'=>22),
7     '5' => array('id'=>6,'prize'=>'下次沒準就能中哦','v'=>50),
8 );

 

$prize_arr是一個二維數組,記錄了全部本次抽獎的獎項信息,其中id表示中獎等級,prize表示獎品,v表示中獎機率。注意其中的v必須爲整數,你能夠將對應的獎項的v設置成0,即意味着該獎項抽中的概率是0,數組中v的總和(基數),基數越大越能體現機率的準確性。本例中v的總和爲100,那麼平板電腦對應的中獎機率就是1%,若是v的總和是10000,那中獎機率就是萬分之一了。數據庫

每次前端頁面的請求,PHP循環獎項設置數組,經過幾率計算函數get_rand獲取抽中的獎項id。將中獎獎品保存在數組$res['yes']中,而剩下的未中獎的信息保存在$res['no']中,最後輸出json個數數據給前端頁面。json

 1 //若是中獎數據是放在數據庫裏,這裏就須要進行判斷中獎數量  2 //在中一、二、3等獎的,若是達到最大數量的則unset相應的獎項,避免重複中大獎  3 //code here eg:unset($prize_arr['0'])
 4 foreach ($prize_arr as $key => $val) {  5     $arr[$val['id']] = $val['v'];  6 }  7 $rid = get_rand($arr); //根據機率獲取獎項id
 8 $res['yes'] = $prize_arr[$rid-1]['prize']; //中獎項  9 //將中獎項從數組中剔除,剩下未中獎項,若是是數據庫驗證,這裏能夠省掉
10 unset($prize_arr[$rid-1]); 11 shuffle($prize_arr); //打亂數組順序
12 for($i=0;$i<count($prize_arr);$i++){ 13     $pr[] = $prize_arr[$i]['prize']; 14 } 15 $res['no'] = $pr; 16 echo json_encode($res);

 

爲何老是抽不到大獎呢?數組

在不少相似的抽獎活動中,參與者每每抽不到大獎,筆者從程序的角度舉個例給你看,假如我是抽獎活動的主辦方,我設置了6個獎項,每一個獎項不一樣的中獎機率,假如一等獎是一臺高級轎車,但是我設置了其中獎機率爲0,這意味着什麼?這意味着參與抽獎者不管怎麼抽,永遠也得不到這臺高級轎車。而當主辦方每次翻動剩下的方塊時,參與者會發現一等獎也許就在剛剛抽獎的方塊旁邊的一個數字下,都怪本身運氣差。真的是運氣差嗎?其實在參與者翻動那個方塊時程序已經決定了中獎項,而翻動查看其餘方塊看到的獎項只是一個煙霧彈,迷惑了觀衆和參與者。我想看完這篇文章後,您或許會知道電視節目中的翻板抽獎貓膩了,您也許大概再不會去機選雙色球了。dom

相關文章
相關標籤/搜索