博主寒冰最近闲来无事。就想研究一下微信红包的金额随机算法。早在微信红包刚出来的时候就研究过。始终不得要领。后来,通过查阅诸多资料。听说要实现“正态分布”。这个理论的东西不想深挖。恰好在网上一篇博客找到一个相对完整的算法。我经过试用确实不错。经过我的一些优化达到了可用级别。
PHP 源码如下:
<?php
class RandMoney
{
/**
* 红包金额(元)
*
* -- 最小值:0.01。
*
* @var float
*/
private $rewardMoney;
/**
* 红包数量
*
* @var int
*/
private $rewardNum;
/**
* 分散度值
*
* -- 1 ~ 10000
* --- 最佳值 100
*
* @var int
*/
private $scatter;
/**
* 执行红包生成算法
*
* @param float $rewardMoney 随机总金额。
* @param int $rewardNum 拆分数量。
* @param int $scatter 分散度值。
* @return void
*/
public function splitReward($rewardMoney, $rewardNum, $scatter = 100)
{
// 传入红包金额和数量。
$this->rewardMoney = $rewardMoney;
$this->rewardNum = $rewardNum;
$this->scatter = $scatter;
$this->realscatter = $this->scatter / 100;
$avgRand = round(1 / $this->rewardNum, 4);
$randArr = [];
while (count($randArr) < $rewardNum) {
$t = round(sqrt(mt_rand(1, 10000) / $this->realscatter));
$randArr[] = $t;
}
$randAll = round(array_sum($randArr) / count($randArr), 4);
$mixrand = round($randAll / $avgRand, 4);
$rewardArr = [];
foreach ($randArr as $key => $randVal) {
$randVal = round($randVal / $mixrand, 4);
$rewardArr[] = round($this->rewardMoney * $randVal, 2);
}
sort($rewardArr);
$rewardAll = array_sum($rewardArr);
$rewardArr[$this->rewardNum - 1] = round($this->rewardMoney - ($rewardAll - $rewardArr[$this->rewardNum - 1]), 2);
rsort($rewardArr);
return $rewardArr;
}
}
调用:
<?phgp
$money = 100; // 总额。
$people = 200; // 红包个数。
$scatter = 100; // 分散度。就是拆成的金额分页更大。
$reward = new RandMoney();
$rewardArr = $reward->splitReward($money, $people, $scatter);
print_r($rewardArr);
大家可以执行一下试试。
网友评论