zoukankan      html  css  js  c++  java
  • php 红包瓜分算法(实用)

    php 红包瓜分算法

    生成的红包总额等于发放的总额,

    本源码解决了
    生成的红包总额小于发放的总额或出现有负数金额以及0元的情况


    例如:我发10元,20个红包,结果生成出来的数组金额之和等于了10元。
    /**
    *
    *调用生成红包的方法
    *
    **/
     public function test()
        {
     $hongbao_arr=$this->getRedPackets($lottery_info['numerical'],$lottery_info['number']);
    var_dump($hongbao_arr) 
    }
    
    
    



    /*
    * *生成红包数组 * @param $total 红包总额 * @param $count 红包个数 * @param $bonus_max 每个小红包的最大额 * @param $bonus_min 每个小红包的最小额 * */ protected function getRedPackets($total = 0, $count = 0) { $yushu = ($total - intval($total)); //如果金额为小数则取出小数位 $bonus_total = ($total - $yushu) * 100; //如果金额为小数则去除小数小计算分配 $bonus_count = $count; $result = array(); if ($bonus_total / $bonus_count > 1) { if (($bonus_total - $bonus_total / 4) / ($bonus_count - 1) >= 1) { $bonus_max = $bonus_total / 4; if (($bonus_total / 4) == ($bonus_total / $bonus_count)) { $bonus_max += 50; } } else { for ($j = 0; $j < $count; $j++) { $result[$j] = ($bonus_total / $bonus_count) / 100; } $r = rand(0, $count - 1); $result[$r] = ($bonus_total - $bonus_count * 1 + 1) / 100; //如果还有负数产生就重新分配 $attr = array(); foreach ($result as $k => $v) { $attr[$k]['money'] = $v; // $attr[$k]['yili'] = 0; } return $attr; } } else { for ($k = 0; $k < $count; $k++) { $result[$k] = $total / $count / 100; } //如果还有负数产生就重新分配 $attr = array(); foreach ($result as $k => $v) { $attr[$k]['money'] = $v; // $attr[$k]['yili'] = 0; } return $attr; } $bonus_min = 1; $average = $bonus_total / $bonus_count; for ($i = 0; $i < $bonus_count; $i++) { //因为小红包的数量通常是要比大红包的数量要多的,因为这里的概率要调换过来。 //当随机数&gt;平均值,则产生小红包 //当随机数<平均值,则产生大红包 if (rand($bonus_min, $bonus_max) > $average) { // 在平均线上减钱 $temp = $bonus_min + $this-> xRandom($bonus_min, $average); $result[$i] = $temp; $bonus_total -= $temp; } else { // 在平均线上加钱 $temp = $bonus_max - $this-> xRandom($average, $bonus_max); $result[$i] = $temp; $bonus_total -= $temp; } } // 如果还有余钱,则尝试加到小红包里,如果加不进去,则尝试下一个。 while ($bonus_total > 0) { for ($i = 0; $i < $bonus_count; $i++) { if ($bonus_total > 0 && $result[$i] < $bonus_max) { $result[$i]++; $bonus_total--; } } } // 如果钱是负数了,还得从已生成的小红包中抽取回来 while ($bonus_total < 0) { for ($i = 0; $i < $bonus_count; $i++) { if ($bonus_total < 0 && $result[$i] > $bonus_min) { $result[$i]--; $bonus_total++; } } } //如果还有负数产生就重新分配 $attr = array(); //随机一个小红包加入金额小数位 $rands = rand(0, ($bonus_count - 1)); $result[$rands] += $yushu * 100; $nums = 0; //处理输出 foreach ($result as $k => $v) { if ($v < 1) { $this-> getBonus(); die; } $attr[$k]['money'] = $v / 100; $nums += $v; } return $attr; } /** * 生成min和max之间的随机数,但是概率不是平均的,从min到max方向概率逐渐加大。 * 先平方,然后产生一个平方值范围内的随机数,再开方,这样就产生了一种“膨胀”再“收缩”的效果。 */ protected function xRandom($bonus_min, $bonus_max) {   //求一个数的平方 $sqr = intval(($bonus_max - $bonus_min)*($bonus_max - $bonus_min)); $rand_num = rand(0, ($sqr - 1)); return intval(sqrt($rand_num)); }
  • 相关阅读:
    [转] DBus学习(一):总体介绍
    [转] DBus学习(四):基础小例子(同步和异步)
    linux系统调用列表
    Quantum Espresso + Phonopy 计算声子过程
    Compile Quantum Espresso (QE)
    Ubuntu 14.04 下创建 svn repository
    Python import 模块导入问题
    修改Ubuntu下ssh登陆时的欢迎信息
    ORNL cadesvirtues上编译 RMG/ Compile RMG on Cadesvirtues at ORNL
    launch images source启动图删除后上下有黑边
  • 原文地址:https://www.cnblogs.com/yuuje/p/14481434.html
Copyright © 2011-2022 走看看