PHP随机红包算法(含最小值)

function demo($total, $num, $min = 0.01)
{
    $overPlus = $total - $num * $min; // 剩余待发钱数
    $base = 0; // 总基数
    // 存放所有人数据
    $container = array();
    // 每个人保底
    for ($i = 0; $i < $num; $i++) {
        // 计算比重
        $weight = round(lcg_value() * 1000);
        $container[$i]['weight'] = $weight; // 权重
        $container[$i]['money'] = $min; // 最小值都塞进去
        $base += $weight; // 总基数
    }

    $len = $num - 1; // 下面要计算总人数-1的数据,
    for ($i = 0; $i < $len; $i++) {
        $money = floor($container[$i]['weight'] / $base * $overPlus * 100) / 100; // 向下取整,否则会超出
        $container[$i]['money'] += $money;
    }

    // 弹出最后一个元素
    array_pop($container);
    $result = array_column($container, 'money');
    $last_one = round($total - array_sum($result), 2);
    array_push($result, $last_one);
    return $result;
}

首先要保底,每个人要拿到一个最低的钱,那么要均分的钱=总钱数-人数*最低金额,lcg_value()这个函数取 0-1的随机数,这里我为了乘了一千则是获取了 0 - 1000的随机数,每个人都分配一个随机数,然后把所有人的随机数全部相加, 每个人的随机数 / 随机数总和,那么就得到了每个人所应分得的钱的比例

这里要注意一点:

  • 最后一个人的钱要用总钱数-之前所有人均分的总金额,否则会有误差
  • 这里用了round()函数是因为php浮点精度问题,不用round(),最后一个人计算的金额会出现 13.230000004638 类似这种情况
  • foo(999999,15000, 12)这个函数在计算比较多的数据的情况,可能偶尔会出现999998.99999999 的这种情况,暂时不清楚如何解决

你可能感兴趣的:(PHP随机红包算法(含最小值))