顺晟科技
2021-08-28 09:41:38
221
抢红包我们当然熟悉,但是你有没有想过怎么实现?
首先要明确需求和需求的约束。红包主要有三个限制
A.抢到的总额=红包总额,不多不少
B.最小值是0.01元,也就是每个人都有一份
C.每个人抢到的红包数量都尽可能平均
假设总金额为M元,N人,每次被抢金额=(0,(M/N) *2),比如还是前面提到的条件,金额为100,人数为10。
个人抢到的金额是(0,20)。根据正态分布,抓取的值应该在10左右。远低于10的概率很小,远大于10的概率也很小。这里假设个人抓10;
第二个人抢的金额是(0,90/9 *2)=(0,20)。和个人一样,第二个人的红包金额也应该在10左右;
我们其他人,等等。
我咨询了“微信红包的架构设计”,就是用的方法。然而,这个算法并不完美。如果个人抓15,第二个人的范围是(0,18.89),如果第二个人抓的很高,对后面的人不利。
接下来,让我们看看如何在golang中实现这个双均值算法
包装主体
导入(
fmt '
数学/兰特
时间
)
func main(){ 0
//10个人抢10000分,也就是10个人抢100元
计数,金额:=int64(10),int64(10000)
剩余:=金额
sum :=int64(0)
对于I :=int 64(0);icount我
x :=双平均值(计数-i,剩余)
保持-=x
总和=x
fmt。Println(i 1,'=',float64(x)/float64(100),',')
}
fmt。Println()
Fmt。Println('总数为: ',sum)
}
//定义可以提前拿1分的更低金额
var min int64=1
//双均值算法
func DoubleAverage(计数,金额int64) int64 {
if计数==1
退货金额
}
//计算更大可用金额
更大:=数量-最小*计数
//计算更大可用平均值
平均值:=更大值/计数
//在双平均的基础上加上更低金额,防止金额为0
avg2 :=2 *平均值最小值
//随机红包金额序列元素,双均值为随机更大值
兰德。种子(时间。现在()。UnixNano())
x :=兰特。Int63n(avg2)最小值
返回x
}
09
2022-04
29
2021-08
28
2021-08
28
2021-08
28
2021-08
28
2021-08