红包平均浮动分配算法

/**
     * 红包随机分配平均值浮动取值方法 最小单位1
     * 生成规则:每个人只能领取人均红包上下10%以内的金额。例如1000块10个人,平均每个人100块,则每个人分配的金额在90-110之间。
     * @date 2021/9/27
     * @param int $total 总值
     * @param int $num 分配数量
     * @param float $float_ratio 浮动比例小数值 0 到 1 之间 0.1代表10%
     * @return array
     */
    public static function generate_red_envelope($total, $num, $float_ratio = 0.1)
    {
        if ($float_ratio < 0 || $float_ratio > 1) {
            return [];
        }

        //计算余数,避免分配的时候有小数,这个数直接分配给第一个人
        $remainder = $total % $num;
        $total     = $total - $remainder;

        //生成数组
        $var_arr = array_pad([], $num, bcdiv($total, $num));

        $distribution = $total * $float_ratio; //待分配

        $change   = 0; //变动的值
        $rand_min = 0;
        $rand_max = $distribution / $num;

        //使用此方法确保循环的数组只循环到双数结尾,如有9个数据只循环到第8个
        $_num = intval($num / 2) * 2;

        //分配
        for ($i = 0; $i < $_num; $i++) {
            $reduce = array_shift($var_arr);
            if ($i % 2 == 0) {
                $change = mt_rand($rand_min, $rand_max);
                $val    = bcsub($reduce, $change);
            } else {
                $val = bcadd($reduce, $change);
            }

            array_push($var_arr, $val);
        }

        if ($remainder) {
            $var_arr[0] = $var_arr[0] + $remainder;
        }

        shuffle($var_arr); //可打乱顺序
        return $var_arr;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值