$tmpItems = ['電腦'=>10, '相機'=>50, '100元現金'=>500]; $proSum = array_sum($tmpItems); foreach ($tmpItems as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $resultId = $key; break; } else { $proSum -= $proCur; } }
從count($tmpItems)總樣本中隨機一個數,循環的判斷是否小於currentValue,小於即是中獎,大於就從總樣本中扔掉currentValue ,繼續循環產生隨機數判斷機率是否落入小於currentValue區間內。算法
封裝爲函數,支持機率爲小數點 (小數點位數越多數據量越大)函數
function get_prize($prizeItems) { $resultId = ''; $dec = explode('.', strval(min($prizeItems))); # 小數點拆分 $dec_len = isset($dec[1]) ? strlen($dec[1]) : ''; #小數點後長度 $radix = 1; # 乘積的基數 if ($dec_len) { for ($i = 1; $i <= $dec_len; $i++) { $radix*=10; } } $tmpItems = []; foreach ($prizeItems as $key => $value) { $tmpItems[$key] = $value * $radix; } $proSum = array_sum($tmpItems); foreach ($tmpItems as $key => $proCur) { $randNum = mt_rand(1, $proSum); if ($randNum <= $proCur) { $resultId = $key; break; } else { $proSum -= $proCur; } } return $resultId; } /** * 電腦 機率爲0.02% 十萬分之二 * 相機 機率爲0.2% 萬分之二 * 100元現金 機率爲1.8% 百分之一點八 * 德芙巧克力 機率爲40% 十分之四 * 謝謝參與 機率爲57.98% 百分之五十七點九八 */ $prizeItems = ['電腦' => 0.0002, '相機' => 0.002, '100元現金' => 0.018,'德芙巧克力'=>0.4,'謝謝參與'=>0.5798]; print_r(get_prize($prizeItems));