假設有如下一個陣列
- $list = array(“A” => 5, “B” => 10, “C” => 15, “D” => 20, “E” => 50);
表示隨機ABCDE,取到A的概率是5%,B為10%,C為15%,D為20%,E為50%。
思路很簡單,畫一根數軸,長度是ABCDE的權值的總和,按照他們的權值,分割這個數軸。
然後隨機取數軸上的一點,落在哪個區間,就取哪個值。
具體演算法如下
- function GetRandom() {
- $list = array(“A” => 5, “B” => 10, “C” => 15, “D” => 20, “E” => 50);
- $sum = 0;
- $listPoint = array(0);//這個陣列記錄了每個切割點的值,就是記錄了數軸上,5,15,30,50,100的值。
- foreach ($list as $key => $value) {
- $sum+=$value;//計算出權值的總和
- array_push($listPoint, $sum);//把分割點放到陣列中
- }
- $num = rand(0, $sum);//取0到sum之間一個隨機值
- //echo $num . “:”;
- for ($i = 0; $i < count($listPoint) – 1; $i++)
- {
- if ($num >= $listPoint[$i] && $num <= $listPoint[$i + 1]) //判斷隨機值落在哪個範圍內
- {
- $elem = array_slice($list, $i, 1);
- return key($elem); //第i項的值
- }
- }
- echo “can`t be here”;
- }
測試程式碼,隨機取100次,看看各個字母出現的次數。
- $a = 0;
- $b = 0;
- $c = 0;
- $d = 0;
- $e = 0;
- for ($i = 0; $i < 100; $i++) {
- $char = GetRandom();
- echo “$char “;
- switch ($char) {
- case “A”:
- $a++;
- break;
- case “B”:
- $b++;
- break;
- case “C”:
- $c++;
- break;
- case “D”:
- $d++;
- break;
- case “E”:
- $e++;
- break;
- }
- }
- echo “A:$a<br>”;
- echo “B:$b<br>”;
- echo “C:$c<br>”;
- echo “D:$d<br>”;
- echo “E:$e<br>”;
- die(0);
得到的結果勉強也能接受。