博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP随机红包算法
阅读量:5991 次
发布时间:2019-06-20

本文共 1996 字,大约阅读时间需要 6 分钟。

2017年1月14日 14:19:14 星期六

一, 整体设计

算法有很多种, 可以自行选择, 主要的"架构" 是这样的, 用redis decr()命令去限流, 用mysql去记录各种需要的数据

二, 红包算法 

简便起见, 红包金额用整数表示, 假设每个红包里边有x个糖豆, 每个人最少一个豆

一种: 每个红包的最大金额是: (剩余金额/剩余红包数)*2, 需要开始的时候预先分配给每个人一个豆

1 function randBean($total_bean, $total_packet) 2 { 3     $min_bean = 1; 4     $max_bean = 5000; 5     $range = 2; 6      7     $total_bean = $total_bean - $total_packet * $min_bean; //每个人预留一个最小值 8  9     $list = [];10     $min = 1;11     while(count($list) < $total_packet){12         $max = floor($total_bean / $total_packet) * $range;13         $bean = rand($min, $max);14 15         if ($bean <= $max_bean - 1) {16             $list[] = $bean;17             $total_bean -= $bean;18         }19     }20 21     $list[] = $total_bean;//剩余的金豆作为最后一个红包22 23     //合并24     foreach ($list as $k => $v) {25         $list[$k] += $min_bean;26     }27 28     return $list;29 }

多次统计

 

第二种, 对其简单扩展一下, 每个红包的最大金额是: (剩余金额/剩余红包数)*3; 但是要求每次最少发2个红包

第三种, 线段法, 随机生成几个数字, 将一个直线分成几段, 每段的长度(这个波动比较大, 不是很平均, 如果限制了每个红包的大小, 会比较麻烦)

1 function abc ($total_bean, $total_packet) 2 {     3     $min = 1; 4     $max = $total_bean -1; 5     $list = []; 6      7     $maxLength = $total_packet - 1; 8     while(count($list) < $maxLength) { 9         $rand = mt_rand($min, $max);10         empty($list[$rand]) && ($list[$rand] = $rand);11     }12     13     $list[0] = 0; //第一个14     $list[$total_bean] = $total_bean; //最后一个15     16     sort($list); //不再保留索引17     18     $beans = [];19     for ($j=1; $j<=$total_packet; $j++) {20         $beans[] = $list[$j] - $list[$j-1];21     }22     23     // return $beans;24     echo '
'; print_r($beans); echo array_sum($beans);25 }26 27 abc(100000, 3);

 

第四种:

因为每人最少1个豆, 那么每次随机生成豆数的时候要预留 剩余人数*1个豆;

去掉这些必须剩余的豆数后, 以剩下的豆数的平均值为最大值进行随机生成本次豆数

 

btw:

抢红包时用redis的一些原子性函数去限流, 然后用MySQL去记录数据

redis配合抢红包使用的函数(一个函数可以干两件事): 

限制每个人只能抢一次

getSet(): 设置值并返回原来的值

setNx(): 如果不存在才设置

红包数量有限, 不能抢超

incr() incrBy() : 增加并返回增加后的值

decr() decrBy(): 减少并返回减少后的值

红包有效期

expire, setTimeout, pexpire(毫秒)

expireAt, pexpireAt(毫秒)

 

转载地址:http://ajtlx.baihongyu.com/

你可能感兴趣的文章
nil、Nil、NULL和NSNull的理解
查看>>
第十二章 springboot + mongodb(复杂查询)
查看>>
微信和WeChat的合并月活跃账户数达到7.62亿了
查看>>
Lintcode--009(单词切分)
查看>>
sqlite3中的数据类型 (转载)
查看>>
Atiitt 使用java语言编写sql函数或存储过程
查看>>
日志文件清理代码
查看>>
Maven属性(properties)标签的使用
查看>>
Tomcat配置https、访问http自动跳转至https
查看>>
vim各种编码设置问题
查看>>
BOOST ASIO 学习专贴
查看>>
HTTP content-type
查看>>
知物由学 | AI时代,那些黑客正在如何打磨他们的“利器”?(一)
查看>>
Mysql 查询decimal 引号‘’增加精度
查看>>
组织分解结构(Organizational Breakdown Structure OBS)
查看>>
跟小静读CLR via C#(09)-扩展方法
查看>>
Flex的UI组件Tile
查看>>
Java中对象的等价性比较
查看>>
windows phone 7中简单使用Usercontrol
查看>>
Graham King » In-memory key-value store in C, Go and Python
查看>>