一、适用场景
红包总金额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:红包数量)
时间: 2024-11-04 16:50:14