一、适用场景
红包总金额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