Maison > développement back-end > tutoriel php > Partager des idées pour implémenter l'algorithme d'enveloppe rouge PHP (avec code de développement)

Partager des idées pour implémenter l'algorithme d'enveloppe rouge PHP (avec code de développement)

藏色散人
Libérer: 2023-04-10 16:28:01
avant
3854 Les gens l'ont consulté
根据很多需求的使用场景,如发红包、砍价类需求,这两个功能都有一个同样的特点,如下:
Copier après la connexion

enveloppe rouge

1. Nombre total d'enveloppes rouges
3. . Combien de personnes sont nécessaires Négociation complète (le nombre de personnes dépend de la demande)

Nombre fixe de personnes à négocier Nombre aléatoire de personnes à négocier

Nombre aléatoire désigné de personnes à négocier
Point 2 : Les trois les règles doivent toutes arriver à un certain nombre de personnes selon les règles

  • 3. Montant minimum de négociation
  • Idées de développement

  • Paramètres de vérification

Le montant minimum ne peut pas être inférieur à 0

Le montant total est ne peut pas être supérieur à la quantité multipliée par le montant minimum

Montant de distribution

Obtenez le montant moyen (montant total/quantité restante)

Montant de distribution Le montant moyen est inférieur ou égal et le montant minimum est directement alloué lorsque le montant maximum est obtenu
Obtenir le montant Rapport d'amplitude La valeur minimale ne doit pas être inférieure à -1 La valeur maximale n'est pas autorisée Supérieur à 1
Le montant de la distribution est obtenu. Calcul de l'amplitude (moyenne * (1+Rapport d'amplitude))
Le jugement du montant de la distribution Montant de la distribution est inférieur au Montant minimum ou au Montant distribué est supérieur au Montant maximum pouvant être réclamé ((Montant minimum + montant total restant) - (Quantité restante × montant minimum))) puis redistribué Le montant

Le dernier montant restant est alloué

Code de développement
小于等于最金额时直接分配最小金额
获取金额幅度比例 最小值不允许小于 -1 最大值不允许大于 1
得出分配金额  幅度计算(平均值*(1+幅度比例))
分配金额判断 分配金额小于最小金额或者分配金额大于 可领取最大金额
<?php

/**
 * 发送红包
 * Class sandRed
 */
class sandRed
{
    #红包金额
    protected $amount;
    #红包个数
    protected $num;
    #领取的红包最小金额
    protected $minAmount;
    #红包分配结果
    protected $amountArr = [];

    public function __construct($amount, $num = 1, $minAmount = 1)
    {
        $this->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(&#39;%01.2f&#39;, round($amount, 2));
    }
}
Copier après la connexion

Montant total

$amount = 1;
Copier après la connexion

Quantité d'allocation
  • $num = 10;
    Copier après la connexion
Montant minimum
  • $minAmount = 0.01;
    
    $red = new sandRed($amount, $num, $minAmount);
    
    $res = $red->handle();
    print_r($res);
    Copier après la connexion
    Sortie résultat [0.10,0. 04,0.08 ,0.04,0.16,0.14,0.11,0.13,0.11,0.09]
    • echo array_sum($res);
      Copier après la connexion
    Résultat de sortie 1
    Apprentissage recommandé : "
      Tutoriel vidéo PHP
    • "

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
php
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal