实时随机数算法(微信红包分配算法)

微信红包算法在知乎上面有个专题讨论,其实红包的发放的随机算法,有两种做法:

1、预生产:

无外乎是在发红包的时候,随机去把金额生成到某个容器当中,然后要用的时候,一个一个的POP;

2、实时随机

用户在抢红包的时候,根据随机算法,算出这次用户要抢到多少


本文讲的是第二种。


之所以没弄第一种,是因为我们的研发同学张智哥,在以前的红包发放算法里面就是用的第二种,而我在征求他的意见看是否改成预生产的时候,他想偷个懒,不想再加表、动流程啥的。我想想也是,动流程动出问题来了,到时候还是得哥背锅。虽然作为研发一直都有丰富的背锅经验和强大的背锅内心,但是,能够少背个还是少背个。

从此,也就开始了我比较黑暗的调整算法、调整参数的过程。

红包算法关键是要简单、迅速的找出随机值,而这个坑,什么正态分布修正、什么平方后再开方取随机数优化,我都尝试过。

结果很惨淡:要么是前面的拿大头的几率很大,要么是后面的拿大头的几率很大,而前面拿大头,或者后面拿大头,是我们运营的大爷们吐槽我们的随机算法做得不如微信好的一个重要原因(尼玛谈需求的时候不讲,还弄了个随机数范围要在8%到74%之间做限制,觉得不爽就让研发背锅)。

废话完了,说下我的算法:

其实很简单,两个随机数,一个随机0到2;一个随机-1到1;两个随机数之和乘以均值,就是这次跑出来的随机数。然后再做下上下限的保护就行了。

我的代码里面偷了个懒,只做了下限,没做上限的保护。因为毕竟是研究算法,不是实际生产环境代码。

	public static void dispath(int total, int people, int min){
		
		for(int i = 0; i < people - 1 ; i++ ){
			int leftPeople = people - i;

			double avg = Double.valueOf(total)/leftPeople;
			double ratio1 = getRandom(0, 2);
			double ratio2 = getRandom(-1, 1);
			double ratio = ratio1+ratio2;
			int cur = (int) Math.floor(ratio * avg) > min ? (int) Math.floor(ratio * avg)  : min;
			
			// 扣减总额阅点数目
			total = total - cur;
			
			System.out.format("第 %d 个红包: %d 阅点,剩下: %d 阅点\n", i + 1, cur,	total);
		}
		
		// 剩余的就是最后一个用户的阅点额度
		System.out.format("第 %d 个红包: %d 阅点,剩下: 0 阅点\n", people, total);	
	}

结果嘛,还马马虎虎,反正跑了几次测试,基本上还可以满足要求,反正最大和最小的,不会固定在某个地方出现了。


  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值