抢红包算法(随机数)

2021-05-13  本文已影响0人  小幸运Q

公平法

红包剩余金额为 M
红包剩余数量为 N

这种算法就是每次都在区间[0,M/N×2] 随机取一个数。假设100元红包发10个人,那么合理的做法应该是每个人领到10元的概率相同。

这样推导下去,每个人领到相同金额的概率应该就是相同的了。

我的解决思路:

第一次生成随机数:k1=(0,sum/n*2) (左开右开区间内的随机数)
第二次生成随机数:k2 = (0,(sum-k1)/(n-1)*2)
第三次生成随机数:k3 = (0,(sum-k1-k2)/(n-2)*2)
第N次生成随机数:kn = sum-k1-...-kn-1

import random
import numpy as np
def getredpocket(sums,n):
    minnum=0.000000001
    # 避免出现0的极端小概率情况
    return random.uniform(minnum,(sums/n)*2-minnum)

def run(sums,n):
    s=[]
    for i in range(n,1,-1):
        red=getredpocket(sums,i)
        sums-=red
        s.append(red)
    s.append(sums)
    for i in s:
        if i<=0:
            print("fuck!!!!")
            # 只要有负数或者0就会在sum函数报错从而发现程序问题
            return "fuck!!!!"
    return s
terms=10000
sums=1000000
n=10000
for i in range(terms):
    r=run(sums,n)
    print("No."+str(i+1)+" terms:")
    print("u:",sum(r)/n,end="   ")
    print("σ:",np.var(r))
    print()
1万人抢100万元红包效果

线段切割法

这个算法可以把总金额想象成一条线段,每个人都有机会切一刀,前面的人切剩下的后面的人再接着切,这样越是前面的人截取的长度(理解成领取到的红包金额)越大的概率就越大。

上一篇 下一篇

猜你喜欢

热点阅读