php红包生成随机算法

 一、适用场景

红包总金额X,分配成Y个红包,每个红包随机金额。

二、生成算法

复制代码
    /**
     * 红包生成算法
     * @param $money    总金额
     * @param $number   红包数量
     * @param $ratio    浮动系数
     */
    function hongbao($money,$number,$ratio = 0.5){
        $res = array(); //结果数组
        $min = ($money / $number) * (1 - $ratio);   //最小值
        $max = ($money / $number) * (1 + $ratio);   //最大值
        /*--- 第一步:分配低保 ---*/
        for($i=0;$i<$number;$i++){
            $res[$i] = $min;
        }
        $money = $money - $min * $number;
        /*--- 第二步:随机分配 ---*/
        $randRatio = 100;
        $randMax = ($max - $min) * $randRatio;
        for($i=0;$i<$number;$i++){
            //随机分钱
            $randRes = mt_rand(0,$randMax);
            $randRes = $randRes / $randRatio;
            if($money >= $randRes){ //余额充足
                $res[$i]    += $randRes;
                $money      -= $randRes;
            }
            elseif($money > 0){     //余额不足
                $res[$i]    += $money;
                $money      -= $money;
            }
            else{                   //没有余额
                break;
            }
        }
        /*--- 第三步:平均分配上一步剩余 ---*/
        if($money > 0){
            $avg = $money / $number;
            for($i=0;$i<$number;$i++){
                $res[$i] += $avg;
            }
            $money = 0;
        }
        /*--- 第四步:打乱顺序 ---*/
        shuffle($res);
        /*--- 第五步:格式化金额(可选) ---*/
        foreach($res as $k=>$v){
            //两位小数,不四舍五入
            preg_match('/^d+(.d{1,2})?/',$v,$match);
            $match[0]   = number_format($match[0],2);
            $res[$k]    = $match[0];
        }

        return $res;
    }
复制代码

由于第五步不四舍五入,所以总金额最多会流失0.01*N元(N:红包数量)

转载原文地址:http://www.cnblogs.com/xiejixing/p/5053275.html

原文地址:https://www.cnblogs.com/wangzhilei/p/6899874.html