锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

红包分配算法的再探究

时间:2023-02-14 00:30:00 200n可代替leuze传感器

再探讨红包分配算法

一、 理论分析,简化红包分配算法

根据上一篇文章中提到的红包分配算法,我们可以将前三步写为以下分段函数:在这里插入图片描述
此时,我们可以发现第二步和第三步可以合并,因此我们可以暂时将第二步和第三步合并为以下分段函数:

让我们把n作为已知量,a获得以下分段函数作为自变量:

这时,我们可以发现,决定x_up分段函数的最终形式有三个关键点,第一个是100n,第二个是199.99 0.01n,第三个是0.01n(n-1)/n-再加上决定x_down的关键点200n-199.99,我们只需要确定这四个点的大小关系就可以最终确定x_down和x_up分段函数的最终形式。可以使用以下代码来确定。

n=np.arange(3, 100, 1) x_down=200*n-199.99 x_up1=100*n x_up2=0.01*n 199.99 x_up3=0.01*(n-1)*n/(n-2) plt.plot(x_down,label ="x_down") plt.plot(x_up1,label ="x_up1") plt.plot(x_up2,label ="x_up2") plt.plot(x_up3,label ="x_up3") plt.legend() plt.show() 


根据上图,我们可以清楚地看到2000n-199.99>100n>0.01n 199.99>0.01(n-1)*n/(n-2)注意n的值范围大于或等于3。事实上,我们不使用代码,只使用数学来证明上述不等式串的建立。所以我们最终决定了x_up分段函数的形式为:

此外,我们还可以在大多数情况下证明数学,x_up函数值大于x_down函数值,重复函数值。

二、 控制变量法探讨红包数量、红包总额与抢劫金额的关系

以下是固定变量法的研究getRedpacket(n,a),即固定红包数量n,红包总额逐步增加a,代码如下。

以下是固定变量法的研究getRedpacket(n,a) #固定红包数量n,红包总额逐步增加a n=5#固定红包数量 a=1200#红包总额从1元开始逐加a,间隔1 times=200 #getRedpacket()函数是随机的,因此平均值应重复多次  money=np.zeros(a 1) for i in range(1, a 1, 1):
    for j in range(times):
        #print("i:",i," j:",j)
        money[i] = money[i]+getRedpacket(n,i)
        
    money[i]=money[i]*n/i/times
plt.title('固定红包个数,红包总金额与抢到金额的关系折线图(已归一化)')
plt.xlabel('红包总金额')
plt.ylabel('抢到的金额')
plt.plot(money)
plt.show()


此时我们可以发现,在固定红包个数为5个的前提下,红包总金额从1元开始增加到1200元的过程中,抢到的金额并不是稳定的,在1元到500元左右的时候,抢到金额经过归一化稳定在1.0附近,也就是说符合随机情况,但是500元之后开始下降,到900元之后又开始上升,这是怎么回事呢?这就应该看本文第一节所说的x_up和x_down的转折点了。当n=5的时候,x_down分段函数的分界点为800.01,x_up分段函数的分界点为0.07和500,完美符合本图。也就是说,如果你发一个含有5个红包的微信红包,那么在500元之内都是符合随机情况,但是在500到800之间,你抢到的金额反而会低于平均值,但是在800之后又会骤增。

我们将红包个数固定为20,也可以发现这种规律。代码如下。

#下面考虑固定变量法研究getRedpacket(n,a)
#固定红包个数n,逐渐增加红包总金额a
n=20#固定红包个数
a=4100#红包总金额,从1元开始逐渐增加红包总金额a,间隔1
times=200 #getRedpacket()函数具有随机性,因此要重复多次取平均值

money=np.zeros(a+1)
for i in range(1, a+1, 1):
    for j in range(times):
        #print("i:",i," j:",j)
        money[i] = money[i]+getRedpacket(n,i)
        
    money[i]=money[i]*n/i/times
plt.title('固定红包个数,红包总金额与抢到金额的关系折线图(已归一化)')
plt.xlabel('红包总金额')
plt.ylabel('抢到的金额')
plt.plot(money)
plt.show()

含有20个红包的微信红包,总金额在2000之前,你抢到金额的期望值都是符合随机的,但是2000到3800之间期望会下降,3800之后又会上升。也是符合x_down和x_up分段函数的。

接下来我们考虑固定红包总金额a,逐渐增加红包个数n的控制变量法来研究红包分配算法。理论分析有些困难,比如x_up的一个分界点,0.01n(n-1)/n-2=a中解出n的取值,就是解如下的二次方程:0.01n*n-(0.01+a)n+2a=0,结果很复杂,而在实际情况中也能发现,比如我们将红包总金额a固定为10,红包个数逐步增加。代码如下。

#固定红包总金额a,逐渐增加红包个数n
n=100#红包个数,从3个开始逐渐增加红包个数至n,间隔1
a=10#固定红包总金额为a
times=500 #getRedpacket()函数具有随机性,因此要重复多次取平均值

money=np.zeros(n+1)
for i in range(3, n+1, 1):
    for j in range(times):
        #print("i:",i," j:",j)
        money[i] = money[i]+getRedpacket(i,a)
    money[i]=money[i]*i/a/times
plt.title('固定红包总金额,红包个数与抢到金额的关系折线图(已归一化)')
plt.xlabel('红包个数')
plt.ylabel('抢到的金额')
plt.plot(money)
plt.show()


10块钱的红包,分成3个到100个发,似乎都是符合随机的,但是我们把个数增加到1000,如下图所示。情况变得很复杂了。感兴趣的朋友可以自己尝试分析以下为什么会出现下面的情况。

同样,我们固定红包总金额为100,红包个数在3-1000都是较为平缓,如下图所示。

但是当个数增加到10000,就会出现下图的复杂规律现象。在此本人不做探究。

三、 画出红包总金额、红包个数与抢到金额的3D图像

第一节我们使用数学分析探讨了红包总金额、红包个数与抢到金额的关系,第二节我们使用控制变量法讨论完了红包总金额、红包个数与抢到金额的关系,接下来第三节我们能否通过绘制3D图像直观的展现出红包总金额、红包个数与抢到金额的关系呢?答案是不行。我们先绘制红包个数2到100,红包总金额1元到1000元的3D图像。代码如下。

#本代码时间复杂度如何?
n=100#红包个数,从2个到100个,间隔1
a=1000#红包总金额,从1元到1000元,间隔1
times=200 #getRedpacket()函数具有随机性,因此要重复多次取平均值
n_1 = np.arange(2, n, 1)#红包个数,从2个到100个,间隔1
a_1 = np.arange(1, a, 1)#红包总金额,从1元到1000元,间隔1
x,y = np.meshgrid(n_1, a_1)
money=np.zeros(shape=x.shape)
for i in range(1, a, 1):
    for j in range(2, n, 1):
        #print("i:",i," j:",j)
        for k in range(times):
            money[i-1][j-2] = money[i-1][j-2]+getRedpacket(j,i)
        money[i-1][j-2]=money[i-1][j-2]*j/i/times
fig = plt.figure()
ax = Axes3D(fig)
surf=ax.plot_surface(x,y,money, rstride=1, cstride=1, cmap=cm.viridis)
ax.set_xlabel('红包个数')
ax.set_ylabel('红包总金额')
ax.set_zlabel('抢到的金额')
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()


图中我们可以看出,一般情况下抢到的金额是符合随机分配的,但是红包个数太少而红包总金额过多,图像就会出现高峰,即抢到的金额就会暴增;而红包个数太多或红包总金额过少,图像就会出现低谷,即抢到的金额就会骤减。但是无法直观的看出具体分界点。下图为红包个数从2-10个,红包总金额取值范围为1-1000元,也能得出上面的结论。

红包个数从2个到5个,红包总金额从1元到1000元,结果图如下。

红包个数从2个到10个,红包总金额从1元到100元,结果图如下。

四、 总结

写完了两篇探究红包分配算法的文章,发现一个小小的红包分配算法竟然有如此多可以研究的点。总的来说,我们研究了以下问题。在第一篇文章中主要探究了抢红包次序与当上运气王概率及抢到金额的关系;第二篇文章即本篇文章,主要探究了红包总金额、红包个数与抢到金额这三者之间的关系。如此说来我有点本末倒置了,事实上最根本的红包分配算法应该不考虑抢红包次序。每抢一次红包只是对红包分配算法的重复调用而已。总的来说,应该先探究最基本的只考虑单次的红包分配算法,再探究和抢红包次序有关的红包分配算法,最后探究红包接龙玩法。

五、 展望

遗憾的是,这两篇文章我也只是出于自己的好奇而随便探究一下,并未得出什么有用的结论。也不能给大家提供什么实用的抢红包策略。无论是只考虑单次的红包分配算法,还是和抢红包次序有关的红包分配算法,还是最后的红包接龙玩法,都浅尝辄止。不过也没关系,毕竟强如清华博士毕导也没有我想的周全。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章