• 微信随机红包算法


      /*
      * 平分红包
      * $sum_money 红包总金额
      * $num 红包个数
      */
      function randBonus($sum_money = 100, $num = 10){
        $list = []; // 将要瓜分的结果
        $bonus_balance = $sum_money; // 每次分完之后的余额
        $bonus_avg = number_format($sum_money / $num, 2); // 平均每个红包多少钱
        $i = 0;
        while($i < $num){
          if($i < $num-1){
            $rand = $bonus_avg; // 根据红包类型计算当前红包的金额
            $list[] = $rand;
            $bonus_balance -= $rand;
          }else{
            $list[] = $bonus_balance; // 最后一个红包直接承包最后所有的金额,保证发出的总金额正确
          }
          $i++;
        }
        return $list;
      }
    
      /*
      * 微信随机红包模拟算法
      * $sum_money 红包总金额
      * $num 红包个数
      * $min_money 红包最小值
      */
      function lottery($sum_money = 100, $num = 10, $min_money = 0.01)
      {
        if ($sum_money < $num * $min_money) {
          return '红包金额不足够瓜分';
        }
        $list = [];
        for ($i = 1; $i <= $num; $i++) {
          // 剩余的可分配金额,需要确保剩下的人每人都至少可以拿到保底的钱
          $remain = $sum_money - array_sum($list) - ($num - $i + 1) * $min_money;
          if ($i < $num) {  // 前面的人随机获得
            // 每轮抽取的金额范围:0 至 剩余金额平均值的两倍
            $get = $this -> random_float(0, $remain / ($num - $i + 1) * 2);
          } else {  // 最后一个人拿全部剩下的
            $get = $remain;
          }
          // 最后再将每个人保底的钱加上
          $list[] = round(round($get, 2) + $min_money, 2);
        }
    
        // 校验红包金额是否有为0或负数,
        foreach ($list as $item) {
          if ($item <= 0.01) {
            $this-> randBonus($sum_money , $num, $min_money);
          }
        }
    
        // 校验总金额是否正确
        $array_sum = array_sum($list);
        if ($sum_money != $array_sum) {
          $this-> randBonus($sum_money , $num, $min_money);
        }
        return $list;
      }
      // 产生一个随机浮点数
      function random_float($min = 0, $max = 1)
      {
        return round($min + mt_rand() / mt_getrandmax() * ($max - $min), 2);
      }
    

      

  • 相关阅读:
    Mysql 怎么限制 IP 访问?
    LA2965 n个数中选出最多个数异或和为0
    UVALive 2678 大于s的最短子序列和
    UVA 1193 区间相关(greedy)
    UVA 11992 线段树
    UVA 1400 线段树
    NBUT 1120 线段树
    最大连续区间和的算法总结(转)
    hiho 1015 KMP
    hiho#1128 : 二分·二分查找
  • 原文地址:https://www.cnblogs.com/seanpan/p/15749413.html
Copyright © 2020-2023  润新知