文章目录

  • 1.前言
  • 2.微信红包模拟器
  • 3.统计结果分析
  • 4.小结

1.前言

微信红包我们天天都在抢,既然是抢红包,我们当然希望是能抢到越多越好,最好是能成为运气王,睥睨群芳。那么怎么才能成为运气王,靠玄学还是靠技术?只要我们足够闲,手机足够多,发出大量的红包,最终能发现其中的统计规律,可以大胆的指出,次序与总人数成黄金分割比的那一位获得运气王的几率最大。

2.微信红包模拟器

当然如果知道了微信红包分配的算法,我们也可以自己写一个红包模拟器来分发红包,获得统计规律。恋猫大鲤鱼在他的博客中介绍了微信红包的随机分配策略。

每次抢红包直接随机,随机的范围是[1, 剩余红包金额均值的两倍],单位分

具体为什么采取这样的分配策略,怎样保证公平可参见原博,这里我关心的是如何实现。
这里以C++为例进行实现,代码如下:

//
//  main.cpp
//  RedBag
//
//  Created by EngzSinger on 2021/3/1.
//#include <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <numeric>
#include <fstream>
#include <string>using std::cout;
using std::cin;
using std::vector;
using std::endl;
using std::accumulate;
using std::ofstream;
using std::string;/** 定义一个红包分配器类*/
class RedBagDistributor
{private:int totalNum; //总红包个数int leftNum; //剩下的红包个数int balance; //余额int totalMoney; //红包总金额int minRand; //红包随机的下限int maxRand; //红包随机的上限,随剩余红包个数和余额的值更新int _Get_Luck_Not_Last(); //最后一个人的金额不是随机得到,所以这里将最后一个人和其他人的分配进行分别实现int _Get_Luck_Last();void _Remove_Bag();//封装leftNum-- 的操作void _Set_Max_Rand();//封装更新maxRand 的操作public:RedBagDistributor() : totalNum(5),leftNum(5),balance(10000),totalMoney(10000),minRand(1),maxRand(4000) {srand((unsigned)time(NULL));}RedBagDistributor(int total_num,int total_money) :totalNum(total_num),leftNum(total_num),balance(total_money),totalMoney(total_money),minRand(1),maxRand(2*total_money/total_num) {srand((unsigned)time(NULL));}int GetLuck(); //抽取红包void ReSet(); // 重设模拟器,避免多次模拟过程中模拟器频繁构造析构带来的消耗
};/** 定义全局函数*/
ofstream &print(ofstream &os,vector<int> vec)
{for(auto &a:vec){os << a <<'\t';}os << endl;return os;
}
double average(vector<int> array)
{size_t num = array.size();int sum = accumulate(array.begin(),array.end(),0);//cout<<num<<'\t'<<sum;return double(sum)/double(num);
}/** 主函数* 进行10000次抢红包模拟,* 红包个数为10,红包总额为100元即10000分* 红包结果写入文件"Record.txt"中*/
int main(int argc, const char * argv[]) {// insert code here...int bag_num = 10;int bag_sum = 10000;int frequency = 10000;string filename = "Record.txt";ofstream fout(filename);RedBagDistributor bador(bag_num,bag_sum);vector<vector<int>> RedBagRecord;RedBagRecord.resize(bag_num);for(auto &a:RedBagRecord){a.resize(frequency);}for(int i=0;i<frequency;++i){for(int j=0;j<bag_num;++j){RedBagRecord[j][i]=bador.GetLuck();}bador.ReSet();}int tmp_counter = 0;for(auto &a:RedBagRecord){tmp_counter++;cout<<"No."<<tmp_counter<<":"<<endl;cout<<"Average = "<<average(a)<<endl;cout<<"Max = "<<*max_element(a.begin(),a.end())<<endl;cout<<endl;}for(auto i=0;i<frequency;++i){vector<int> tmp;for(auto j=0;j<bag_num;++j) tmp.push_back(RedBagRecord[j][i]);print(fout,tmp);}return 0;
}/** 类内函数的实现*/
void RedBagDistributor::_Remove_Bag()
{leftNum--;
}
int RedBagDistributor::_Get_Luck_Not_Last()
{auto get_value = (rand() % (maxRand-minRand+1))+minRand;balance -= get_value;_Remove_Bag();return get_value;
}
int RedBagDistributor::_Get_Luck_Last()
{_Remove_Bag();return balance;
}int RedBagDistributor::GetLuck()
{//if(leftNum==0) //exception_Set_Max_Rand();if(leftNum==1)return _Get_Luck_Last();elsereturn _Get_Luck_Not_Last();
}
void RedBagDistributor::_Set_Max_Rand()
{maxRand = 2*(balance/leftNum);
}
void RedBagDistributor::ReSet()
{leftNum = totalNum;balance = totalMoney;_Set_Max_Rand();//srand((unsigned)time(NULL));//秒级时间,程序运行过程中没有变化
}

3.统计结果分析

  • 首先是程序在标准输出设备的输出信息,可以看到对于每一个参与抢红包的人,所能获得红包的期望都在总体平均值附近浮动,这也比较符合红包设计的初衷,尽量保证分配过程的公平。细心观察不难发现,其中第六位能获得红包的平均值为1015.24,在所有人中比较突出,我们选择的总人数为10人,黄金分割位正好是第六个,所以充分验证我们开篇的猜想! 当然不是,我差点都信了,这只是一个巧合,多运行几次结果就不是第六个的平均值最大了。
    平均值大家都一样,而最大值就比较有意思了,可以发现越往后能获得的最大值越大。其实这也好理解,随机范围的最大值是剩余均值的两倍,假设前面的人抢到的数值足够小,那么越往后剩余均值越大,对应的随机范围最大值也越大。
No.1:
Average = 991.353
Max = 2000No.2:
Average = 998.175
Max = 2214No.3:
Average = 1001.36
Max = 2439No.4:
Average = 1001.67
Max = 2760No.5:
Average = 997.317
Max = 3067No.6:
Average = 1015.24
Max = 3240No.7:
Average = 1007.83
Max = 3771No.8:
Average = 995.736
Max = 4383No.9:
Average = 988.318
Max = 5148No.10:
Average = 1003
Max = 5956
  • 前面只是看到了每一位最大值,结果具有随机性,为了能看到更广泛的分布,我们可以把输出到文件的内容在Excel中进行处理,将每个位置对应的所有红包进行排序,绘制不同位置的红包散点图,看每个位置能拿到红包中最大若干个值的比较。可以看到位置越往后,获得的红包值上限越大。

4.小结

  • 不管排在那个位置,获得红包的期望都是总体均值,但是越往后能获得的最大值越大,换言之,越往后越刺激。
  • 按照红包分配策略,最后一个人能拿到的是倒数第二个人抢完后的余额,两个人的红包应该差不多,但是从图中可以看出第九个人与第十个是相比有一点略微的优势。是因为统计样本不够大,还是因为数学原理掌控了结果?
  • 本文实现的模拟器放弃了对最后一个红包的限制,导致最后一个人可能抢到0元,如何优雅的解决这个问题。

微信群红包模拟器-怎样抢最大的红包相关推荐

  1. 软件测试用例设计之微信群抢红包经典用例

    好吧,本人在游逛各大招聘网站时,看到这个题目:为微信群发红包抢红包设计测试用例.虽然,本人也是测试小白,现在正在找软件测试的工作,然后宝宝就花了点心思写了下测试case,我觉得帮助还是挺大的!最重要的 ...

  2. 微信群抢小程序分享的红包

    最近项目上线了一个小程序抢红包的迭代,其实小程序是目前是没有开放这个接口的,抢红包接口目前只对公众号开放,怎么实现的是不是大家很好奇呢? 首先,我们先来分析小程序抢红包功能的使用场景,在小程序里面微信 ...

  3. python实现抢劵_用Python实现微信自动化抢红包,再也不用担心抢不到红包了

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 ... 过了一会, ...

  4. 微信抢红包python脚本不用手机_用Python实现微信自动化抢红包,再也不用担心抢不到红包了...

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 - 过了一会,内心 ...

  5. 红包随机算法微信群红包随机算法

    文章目录 1.前言 2.参考微信群红包算法 3.一个可用的随机算法 参考文献 1.前言 因疫情影响,部门 2021 年会以线上直播的形式进行,通过微信小程序展开.为活跃年会氛围,年会直播间会有抢红包环 ...

  6. 从用户个体的角度,谈微信群吱口令红包

    作者:柳不浪 全文共 4306 字,阅读需要 10 分钟 ---- / BEGIN / ---- 本文仅从用户个体的角度,来聊聊至今不绝于微信群的吱口令红包. "邀请朋友领红包,当TA到店付 ...

  7. 微信红包雨怎么抢_微信红包雨怎么发出? 微信红包雨发送技巧有哪些?

    微信红包雨怎么发出? 微信红包雨发送技巧有哪些?小编最近学会了一项技能,那就是发微信红包雨,一包多发,有对微信红包雨怎么发出感兴趣的伙伴吗,接下来小编与您分享下微信红包雨怎么发出吧. 微信红包雨怎么发 ...

  8. python实现自动化抢微信红包功能_【Python】用Python实现微信自动化抢红包,再也不用担心抢不到红包了...

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 - 过了一会,内心 ...

  9. python自动抢微信红包源码_用Python实现微信自动化抢红包,再也不用担心抢不到红包了...

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 ... 过了一会, ...

最新文章

  1. django修改服务器名称,django部署和服务器配置教程
  2. 线程模型、pthread 系列函数 和 简单多线程服务器端程序
  3. 正则表达式中(?:)的巨大作用
  4. Go语言生成区间随机数
  5. 腾讯云数据库 MySQL 8.0 正式上线,性能全面超越官方版本
  6. python 接口测试 如何写配置文件_python接口自动化测试 - configparser配置文件解析器详细使用...
  7. Linq(筛选与排序)
  8. 什么是机器学习?(上)
  9. Flex初学者群(54200135)共享资料清单-----2008.1.24
  10. drawio中添加数学公式
  11. Gensim库的使用——Doc2Vec模型(一)介绍与使用
  12. copyonwritearraylist 深究
  13. js 移动号码,座机号码,座机转分机号码验证
  14. DBveaver的一些使用心得
  15. python数据清洗面试题_利用python进行数据清洗
  16. 使用magick 遇到 convert: Non-conforming drawing primitive definition `text'错误的解决办法...
  17. 传感器与检测技术基础 复习提纲 考试不挂科专用版
  18. 网站日志分析(二)——利用Quick BI制作企业化报表分析
  19. Java基础IO系列之ByteArrayInputStream和ByteArrayOutputStream解析
  20. 第一只python小爬虫

热门文章

  1. 利用webSocket实现扫码登录PC端
  2. HEVC/H.265面试问题准备(PART 3. 环路滤波+熵编码)
  3. IEEE 期刊双栏模板引用文献问题
  4. 数据结构——AOV图与算法——拓扑排序
  5. 【自然语言处理】【细粒度情感分析】细粒度情感分析:了解文本情感的What、How、Why
  6. JDK 8的新特性-Lambda表达式 精品文章总结
  7. echarts 曲线走势图
  8. cad标注桩号lisp_CAD插件标桩号的AutoLISP程序语言求解释并译成中文,谢谢
  9. 计算机组成原理——乘法运算(一位乘)
  10. 《如何发掘高潜力人才-合伙人-阿根廷费洛迪》 读后感