/** * 砍價算法-生成砍價金額 * * @param int $people 砍價人數或次數 * @param int $amount 砍價總額 單位元 * @param int $min 最低砍價金額 不得低於0 * @param int $max 最高砍價金額 砍價次數 * 最高砍價金額不得小於砍價總額 * @param int $level 層級 防止遞歸超出限制 * * @return array */ function genRandomAmount($people = 0, $totalAmount = 0, $min = 0, $max = 0, $level = 1) { // 防止遞歸超出限制報異常,提前退出 if ($level == 200) { return []; } $arr = []; // 數據錯誤直接返回 if (empty($people) || empty($totalAmount)) { return []; } // 轉換成分便於計算 $tmpTotal = $totalAmount * 100; $tmpMin = $min * 100; $tmpMax = $max * 100; // 計算n-1次的隨機金額,如果不減1,則會出現多減一次隨機金額的問題,應該是最后的金額直接賦值 for ($i = 0; $i < $people - 1; $i++) { $arr[$i] = mt_rand($tmpMin, $tmpMax); $tmpTotal = $tmpTotal - $arr[$i]; } // 最后的價格直接使用最后剩余的價格 $arr[$people - 1] = $tmpTotal; // 最后一次價格小於最小金額或者大於最大金額都不對,繼續遞歸重新計算 if ($tmpTotal < $tmpMin || $tmpTotal > $tmpMax) { return genRandomAmount($people, $totalAmount, $min, $max, $level + 1); } // 返回單位元的數據 return array_map(function ($value) { return $value / 100; }, $arr); } /** * 砍價算法-獲取砍價金額 * * @param int $people 砍價人數或次數 * @param int $amount 砍價總額 * @param int $min 最低砍價金額 不得低於0 * @param int $max 最高砍價金額 砍價次數 * 最高砍價金額不得小於砍價總額 * * @return array */ function getRandomAmount($people = 0, $totalAmount = 0, $min = 0, $max = 0) { // 數據錯誤直接返回 if (empty($people) || empty($totalAmount)) { return []; } if ($people * $max <= $totalAmount) { return false; } $arr = genRandomAmount($people, $totalAmount, $min, $max); // 有幾率會因為遞歸調用超出限制而返回空數組,這里繼續重新生成,直到金額正確 while (empty($arr)) { $arr = genRandomAmount($people, $totalAmount, $min, $max); } return $arr; }