Home>Article>Backend Development> Share ideas for implementing PHP red envelope algorithm (with development code attached)

Share ideas for implementing PHP red envelope algorithm (with development code attached)

藏色散人
藏色散人 forward
2021-09-03 15:50:59 3699browse
根据很多需求的使用场景,如发红包、砍价类需求,这两个功能都有一个同样的特点,如下:

红包

1.Total amount
2.Number of red envelopes
3.Min. Number of red envelopes

Bargaining

1. Total bargaining amount
2. How many people are needed to complete the bargaining (the number of people depends on the demand)

  • Fixed Number of Bargaining Numbers
  • Random Bargaining Number of Numbers
  • Specified Random Bargaining Number of People
    Point 2: The three rules all need to determine a number of people according to the rules

3. Minimum bargaining amount

Development ideas

Verification parameters

The minimum amount is not allowed to be less than 0
Total The amount is not allowed to be greater than the quantity multiplied by the minimum amount

Distribution amount

Get the average amount (total amount/remaining quantity)

Distribution amount Average amount less than or equal toDirectly allocate the minimum amount when the maximum amount is reached
Get the amount Amplitude ratioThe minimum value is not allowed to be less than -1The maximum value is not allowed to be greater than 1
Obtained Distribution amount amplitude calculation (average * (1 amplitude ratio))
Distribution amount judgment Distribution amountis less than minimum amountor distribution amountis greater than The maximum amount that can be claimed((minimum amount remaining total amount) - (remaining quantity × minimum amount)) will redistribute the amount
If the last one is left, all the remaining amounts will be distributed

Development code

amount = $amount; $this->num = $num; $this->minAmount = $minAmount; } /** * 处理返回 * @return array * @throws Exception */ public function handle() { # 验证 if ($this->amount < $validAmount = $this->minAmount * $this->num) { throw new Exception('红包总金额必须≥'.$validAmount.'元'); } # 分配红包 $this->allot(); return $this->amountArr; } /** * 分配红包 */ protected function allot() { # 剩余可分配的红包个数 $num = $this->num; # 剩余可领取的红包金额 $amount = $this->amount; while ($num >= 1) { if ($num == 1) { # 剩余一个的时候,直接取剩余红包 $coupon_amount = $this->formattingAmount($amount); } else { # 平均金额 $avgAmount = $this->formattingAmount($amount / $num); # 分配金额 $countAllotAmount = $this->countAllotAmount($avgAmount, $amount, $num); # 剩余的红包的平均金额 $coupon_amount = $this->formattingAmount($countAllotAmount); } # 追加分配金额 $this->amountArr[] = $coupon_amount; # 计算剩余金额 $amount -= $coupon_amount; $num--; } # 随机打乱 // shuffle($this->amountArr); } /** * 计算分配的红包金额 * @param float $avgAmount 每次计算的平均金额 * @param float $amount 剩余可领取金额 * @param int $num 剩余可领取的红包个数 * @return float */ protected function countAllotAmount($avgAmount, $amount, $num) { # 如果平均金额小于等于最低金额,则直接返回最低金额 if ($avgAmount <= $this->minAmount) { return $this->minAmount; } # 浮动比率 $floatingRate = $this->floatingRate(); # 分配金额 $allotAmount = $avgAmount * (1 + $floatingRate); # 浮动计算 $coupon_amount = $this->formattingAmount($allotAmount); # 如果低于最低金额或超过可领取的最大金额,则重新获取 if ($coupon_amount < $this->minAmount || $coupon_amount > $this->canReceiveMaxAmount($amount, $num)) { return $this->countAllotAmount($avgAmount, $amount, $num); } return $coupon_amount; } /** * 计算分配的红包金额-可领取的最大金额 * @param $amount * @param $num * @return float|int */ protected function canReceiveMaxAmount($amount, $num) { return $this->minAmount + $amount - $num * $this->minAmount; } /** * 红包金额浮动比例 * @return float|int */ protected function floatingRate() { # 60%机率获取剩余平均值的大幅度红包(可能正数、可能负数) if (rand(1, 100) <= 60) { # 上下幅度70% return rand(-70, 70) / 100; } # 其他情况,上下浮动30%; return rand(-30, 30) / 100; } /** * 格式化金额,保留2位 * @param $amount * @return string */ protected function formattingAmount($amount) { return sprintf('%01.2f', round($amount, 2)); } }
  • Total amount
$amount = 1;
  • Allocation quantity
$num = 10;
  • Minimum amount
$minAmount = 0.01; $red = new sandRed($amount, $num, $minAmount); $res = $red->handle(); print_r($res);
  • Output result [0.10,0.04,0.08,0.04,0.16,0.14,0.11,0.13,0.11,0.09]
echo array_sum($res);
  • Output result 1

Recommended learning: "PHP Video Tutorial"

The above is the detailed content of Share ideas for implementing PHP red envelope algorithm (with development code attached). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete