微信红包算法研究

微信红包在发送时已生成所有金额,遵循类似截尾正态分布,使得平均值接近,避免手气最佳过于集中。红包金额在剩余总人数的均值基础上,通过正态分布随机产生,并限制最后一个红包的大小。代码实现中包含随机数的正态分布校验,以确保红包分配的趣味性。实际微信红包可能还有更多复杂处理,以增强用户体验。
摘要由CSDN通过智能技术生成

背景:之前过年亲戚人都在抢红包,都想抢第一个,说是越早抢越大。其实这肯定是不正确的,微信在你发红包的时候应该已经生成所有的红包了,所以说你无论第几个抢,按说应该都一样,除非微信做了一些处理,比如说越早抢红包越可能手气最佳,过完年回来上班,突然想起了微信红包,就在想微信红包生成的策略。

20块钱10个红包,人均2块钱。因为理论上红包的金额应该在2块钱左右,而且越大概率越小,感觉这个很像正态分布函数,所以感觉微信红包属于截尾正态分布。手气最佳一般在2倍-3倍左右。
类似于这种(网上找的图):
这里写图片描述

所有红包在发送者发红包的时候都已经生成好了,领红包只是领生成的红包而已,点击别人发的红包,只会计算你点击的那一时刻还有没有红包,如果没有了,你就只能查看details了,所以说打开的时候出现的那个拆字相当于一个令牌,你可以凭借这个令牌去领红包,当然这个令牌在领红包的时候也有可能红包被领完了,所以你也就回去看details了,如果领到了就会告诉你领了多少钱。

每一次从红包金额池里随机出的金额应该是当时剩余总人数的均值,比如第一个人抽应该基于2的正态分布,如果他抽了4块钱,那么随机第二个红包的时候自然是基于16/9的正态分布,以此往后推,抽到倒数第一个就不用抽了,直接把剩下的都分了就行。而且因为红包最小是0.01嘛,所以每一次抽奖的时候都得留够足够的钱来用于发放剩下的红包,随意每一次随机都得判断。而且我做了一个限额倍数,因为随机出来的数字很可能在均值偏下的地方,多个累积起来,很可能就会造成最后一个红包过大的可能,所以我做了调整,当最后一个红包大于一定的倍数的时候,需要重新抽。另外,按这样抽奖,第一个人的均值应该最大,所以我在最后对生成的红包打乱了顺序。

随机生成红包的代码,做了一些简单的封装。
若Y~N(a,b^2) (b>0),则X=(Y-a)/b~(0,1)

package com.galaxy.fym.algorithm.maxsublist;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by fengyiming on 2017/2/17.
 *
 * @author fengyiming
 *         随机产生红包:金额正太分布
 *
 *         如果非标准正态分布X~N(μ,σ^2),那么关于X的一个一次函数 (X-μ)/σ ,就一定是服从标准正态分布N(0,1)。
 *         举个具体的例子,一个量X,是非标准正态分布,期望是10,方差是5^2(即X~N(10,5^2));那么对于X的线性函数Y=(X-10)/5,Y就是服从标准正态分布的Y~N(0,1)。
 */
public class RedPacket {
   

    private static Random random = new Random();

    private static BigDecimal MIN_VALUE = new BigDecimal("0.01");

    private static boolean isMin = false;

    /**
     * 生成红包
     *
     * @param amountValue 红包总金额
     * @param sizeValue   红包大小
     * @param maxMutValue 剩余红包限定倍数
     * @param sigmaValue  标准差倍数
     * @return
     */
    public static List<BigDecimal> getAllHotPacket(
  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值