雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

PHP 拼手气红包分配算法

2024-09-23 17

1. 前言


在公司的一个项目中有红包抽奖活动,其中有拼手气红包。

在网上找了别人封装的红包分配算法,但是都存在问题,索性就自己手写了一个

2. PHP 拼手气红包分配算法


/** * 拼手气红包分配算法 * * @param $money  金额 * @param $count 数量 */function redAlgorithm($money, $count){    // 参数校验    if ($count * 0.01 > $money) {        throw new \Exception("单个红包不能低于0.01元");    }    // 存放随机红包    $redpack = [];    // 未分配的金额    $surplus = $money;    for ($i = 1; $i <= $count; $i++) {        // 安全金额        $safeMoney = $surplus - ($count - $i) * 0.01;        // 平均金额        $avg = $i == $count ? $safeMoney : bcdiv($safeMoney, ($count - $i), 2);        // 随机红包        $rand = $avg > 0.01 ? mt_rand(1, $avg * 100) / 100 : 0.01;        // 剩余红包        $surplus = bcsub($surplus, $rand, 2);        $redpack[] = $rand;    }    // 平分剩余红包    $avg = bcdiv($surplus, $count, 2);    for ($n = 0; $n < count($redpack); $n++) {        $redpack[$n] = bcadd($redpack[$n], $avg, 2);        $surplus = bcsub($surplus, $avg, 2);    }    // 如果还有红包没有分配完时继续分配    if ($surplus > 0) {        // 随机抽取分配好的红包,将剩余金额分配进去        $keys = array_rand($redpack, $surplus * 100);        // array_rand 第二个参数为 1 时返回的是下标而不是数组        $keys = is_array($keys) ? $keys : [$keys];        foreach ($keys as $key) {            $redpack[$key] = bcadd($redpack[$key], 0.01, 2);            $surplus = bcsub($surplus, 0.01, 2);        }    }    // 红包分配结果    return $redpack;}
更新于:16天前
赞一波!

文章评论

评论问答