本文最后更新于2021-06-22,已超过 1年没有更新,如果文章内容、图片或者下载资源失效,请留言反馈,我会及时处理,谢谢!
温馨提示:本文共2043个字,读完预计6分钟。
描述:给定总积分,给定总人数,给定最大与最小值产生随机数
源代码:
public function getBonus()
{
$total_point = 32000; //单位:分
$total_people = 20;
$point_max = 2000; //单位:分
$point_min = 1000; //单位:分
$bonus = $this->_getBonus($total_point, $total_people, $point_max, $point_min);
return ajax_success('ok', $bonus);
}
/**
* 功能:求一个数的平方
* @param $n
* @return float|int
*/
public function _sqr($n)
{
return $n * $n;
}
/**
* 功能:产生红包
* @param $total_point
* 红包总额
* @param $total_people
* 红包个数
* @param $point_max
* 每个小红包的最大额
* @param $point_min
* 每个小红包的最小额
* @return array
* 存放生成的每个小红包的值的一维数组
*/
public function _getBonus($total_point, $total_people, $point_max, $point_min)
{
$result = array();
$average = $total_point / $total_people;
if ($point_max < $average) {
for ($i = 0; $i < $total_people; $i++) {
$result[$i] = $point_max;
}
return $result;
}
if ($point_min > $average) {
for ($i = 0; $i < $total_people; $i++) {
$result[$i] = $average;
}
return $result;
}
for ($i = 0; $i < $total_people; $i++) {
//因为小红包的数量通常是要比大红包的数量要多的,因为这里的概率要调换过来。
//当随机数>平均值,则产生小红包
//当随机数<平均值,则产生大红包
if (rand($point_min, $point_max) > $average) {
// 在平均线上加积分
$temp = $point_min + $this->_xRandom($point_min, $average);
$result[$i] = $temp;
$total_point -= $temp;
} else {
// 在平均线上减钱
$temp = $point_max - $this->_xRandom($average, $point_max);
$result[$i] = $temp;
$total_point -= $temp;
}
}
// 如果还有余积分,则尝试加到小红包里,如果加不进去,则尝试下一个。
while ($total_point > 0) {
for ($i = 0; $i < $total_people; $i++) {
if ($total_point > 0 && $result[$i] < $point_max) {
$result[$i]++;
$total_point--;
}
}
}
//如果积分是负数了,还得从已生成的大于最小红包的红包中抽取回来
while ($total_point < 0) {
for ($i = 0; $i < $total_people; $i++) {
if ($total_point < 0 && $result[$i] > $point_min) {
$result[$i]--;
$total_point++;
}
}
}
return $result;
}
/**
* 功能:生产 min 和 max 之间的随机数,但是概率不是平均的,从 min 到 max 方向概率逐渐减小。
* 先平方,然后产生一个平方值范围内的随机数,再开方,这样就产生了一种 膨胀 再 收缩 的效果。
* @param $point_max
* 每个小红包的最大额
* @param $point_min
* 每个小红包的最小额
* @return int
*/
public function _xRandom($point_min, $point_max)
{
$sqr = intval($this->_sqr($point_max - $point_min));
$rand_num = rand(0, ($sqr - 1));
return intval(sqrt($rand_num));
}
返回示例:返回的数据单位也是分。
{
"code": 200,
"msg": "ok",
"content": [
1652,
1556,
1853,
1814,
1784,
1572,
1819,
1051,
1850,
1519,
1317,
1752,
1579,
1557,
1417,
1602,
1694,
1427,
1542,
1643
]
}