红包算法思考和总结

参考:

http://mp.weixin.qq.com/s?__biz=MzI2NjA3NTc4Ng==&mid=402360599&idx=1&sn=69318b235e0e8b402d6fc566a3355af4&scene=0#wechat_redirect

进入知乎《微信红包的随机算法是怎样实现的》查看更多人的算法。

最近看到抢红包这么火,早就想尝试去把抢红包的功能试着去做一做了。刚好今天看到参考的网址,就产生了这一篇总结性的文章了。

我的早期逻辑猜想?

  1. 发红包者在发红包的时候,内存中存放的是红包的总额和红包的个数。然后在用户点击“拆红包”的时候,向服务器接口请求,服务器逻辑给用户计算出一个随机值(红包多少钱?),返回给前端。依次类推。
  2. 每次计算随机值时,都是用剩余的钱数除剩余拆红包的人,得出一个平均值,利用这个平均值去平衡每一个抢红包的用户得到的钱。
  3. 并没有第三,谢谢。

不过,看完参考的文章,思路还是有一定的改进的。在每个用户点击”拆红包”的时候,并没有像我想象中的那样去计算用户获得多少钱的红包,而是在发红包的时候(就是输入总额和红包个数,付款后并提交到服务器的时候),服务器就已经计算出每个红包的额度并存放到内存中了。那么当每个用户点击”拆红包”的时候,服务器直接就把”结果”(红包的数值)给前端就完成了一次领红包的操作了。从性能上看,这种方法明显优于我之前的想法,但是,从存储空间上分析,如果发的红包个数太多的话,就会非常消耗内存了。

===============================================================================

逻辑代码:

<?php

$total_money = 1000;//发红包的总额,单位:分
$num = 8;//发红包的个数
$min_money = 1;//每个人至少得到多少钱?

for ($i = 1; $i <= $num; $i++) {
   if ($i == $num) {//最后一个红包就直接等于余额
      $money = $total_money;
      $total_money = 0;
   } else {
      //$max_money是整个算法比较重要的部分,这个数值如果得到决定了红包活动的公平性。
      //这里只是比较简单的一种方式,如果真要当功能去做的话,这里的max_money值获取的算法肯定是要优化的。
      $max_money = $total_money / ($num-$i);//
$total_money相当于整个红包的余额,$num-$i相当于剩下还有多少人没有领红包
      $money = mt_rand($min_money, $max_money);
      $total_money -= $money;
   }
   $money /= 100;
   $tmp = $total_money / 100;
   echo "第{$i}个红包的数值为{$money}元, 余额为: {$tmp}元\n";

===============================================================================

时间: 2024-11-03 21:35:56

红包算法思考和总结的相关文章

红包算法

今天看到一个红包算法,就使用了拿来主义 $total=10; //总额 $num=8; // 分成8个红包,支持8人随机领取 $min=0.10; //每个人最少能收到0.10元 for ($i=1;$i<$num;$i++) { $safe_total=($total-($num-$i)*$min)/($num-$i);//随机安全上限 ,这里算的是剩余的钱除以剩余的人的平均值 $money=mt_rand($min*100,$safe_total*100)/100; $total=$tota

微信红包算法

微信红包有多种玩法,其中一种就是指定金额.人数(m),拆红包的人收到的金额是随机,收到的金额保留两位小数,至少有一分,所有人的红包加起来等于指定金额. 我想到一种做法就是:将指定金额放大100倍,也就是变成单位"分",这时金额就是整数了,设为n,从1到n这个整数区间随机抽取m(是人数)个整数,这样1到n的整数区间就分成了m或m+1(这种情况,最后的两个区间合成一个区间)个区间. 比如输入金额1.00元,人数m=3,n=100 * 1.从1到100之间随机选中的三个整数为15.42.88

微信红包算法TEST

1.基本算法 设定总金额为10元,有N个人随机领取:N=1 则红包金额=X元: N=2 为保证第二个红包可以正常发出,第一个红包金额=0.01至9.99之间的某个随机数 第二个红包=10-第一个红包金额: N=3 红包1=0.01至0.98之间的某个随机数 红包2=0.01至(10-红包1-0.01)的某个随机数 红包3=10-红包1-红包2 -- 2.java代码 1 package Demo_1.Test_1; 2 3 import java.math.BigDecimal; 4 impor

发手气红包算法

lowest=0.01元,最小金额 操作是整数,最小人民币单位是分,所以有2位小数,最少是0.01元 发n人,就取1到100的随机数n个 n个数相加得到总份量,用总发红金额total去除,得到每一份的金额 per=total/n 开始发红包 若n个数中不幸取到0,拿不能给0,给一个最小数lowest 0.01元 基它是 permount=pernum*per/100 发到倒数第二个,最后一个不能按照公式发,要总数total-已发金额,(原因是上每份金额保留两位小数时,采用四舍五入) 举例说明:6

求一个红包算法

m个硬币,n个红包,红包里的硬币数不可以小于b,也不可以大于t,数目是随机的. mnt均为自然数,且 n*b<=m<=n*t. 求红包算法 function getRedPackets(m,n,b,t){ var ret = new Array(n); /*todo*/ return ret; }

算法思考

A - Count on Canton Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Description One of the famous proofs of modern mathematics is Georg Cantor's demonstration that the set of rational numbers is enumerable.

关于微信手气红包算法的探讨

关于微信手气红包算法的探讨 前言 这大过年的,长辈家人朋友发的红包抢到手软,嘿嘿嘿.昨晚,和一个朋友出去浪,刚好两人现在就读专业相同,不知不觉间就谈到了微信红包的算法.今天闲来无事,就简单的做了一下记录. 第一种 这个是最简单的实现,就是先给每个红包分配0.01(确保大家都有),然后各个红包轮流产生一个随机数(不得大于当前总金额)并从总金额中取出相应的数,最后一个红包不管如何,全盘接收总金额. 贴 java 代码: ```java /** * 最简单的分配方法,单位全部统一为 分 * @para

一个效率比较高红包算法

提供一个红包算法,随手写的,还有很多需要优化的地方,但是效率比较高, 测试效率:一百万次 ,20 个红包的  需要 1.3 秒左右 一百万次 ,100 个红包的  需要 6.3 秒左右 代码实现: import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 计算红包分配 * * @author LENOVO * */ public final class RedPacketUtil { pub

红包算法的一种实现(PHP)

前段时间有个项目需要用到红包算法,本以为简单,细想之下有点复杂.于是就百度了一下,没想到查出了不少,有些写的很复杂.由于时间有点紧,我就找了一个简单点的.然后参考着写一个.参考的地址是:https://blog.csdn.net/gorgle/article/details/52954413: 这个地址中的红包是用java写的.根据其原理,我用PHP写了一遍,并且改进了点.他的算法中没有加每个红包最大最小值限制.我用PHP写的时候加上去了.代码如下: <?php /* $total_money: