砍價獲取金額

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章