本文最后更新于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 ] }