/**
* 砍價算法-生成砍價金額
*
* @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;
}