求微信红包赌博的赢钱期望

2018-11-12  本文已影响0人  某某香肠

前段时间看到了一则微信红包赌博群的广告,公布的规则如下:

  1. 10元发4包,互相抢,抢到金额最小的需要接龙(再发一个10元的红包,就这么接龙下去),如果群主金额最小,则倒数第二人接龙,如果出现多个数值一样,则猜拳接龙
  2. 如果抢到了固定金钱,则可以叫群主返现,具体规则对应如下:
抽红包金额 反现金额 抽红包金额 反现金额
1.11 11.1 1.23 12.3
2.22 13.33 4.44 15.55
3.33 22.2 2.34 23.4
4.56 16.66 5.67 18.88
7.77 40 6.78 40
8.88 88.8 7.89 40

下面来求一下玩家赢钱的期望

基本思路

微信红包实现机制模拟

微信红包的金钱分配机制未知,假设其实现方式如下:

方便起见,先忽略掉规则2,来算一下玩家1的期望

期望计算

假设玩家1所分到的金钱为i,而在这个前提下收入的期望为E[i],不难得出期望的计算公式为:
E = E[1] +E[2] + ...+ E[i] + ... + E[997]
下面计算E[i]:

当玩家1得到的金钱为i时,总共的组合数为C_{999-i}^2(第一个隔板确定放在第i个间隙上,而它其余的隔板都不能房子其左边的间隙上)

由于群主一定拿到红包,实际上就是取另外3个人最小值进行红包接龙,最极端的条件是群主只拿到1分钱,剩下999分分摊给其他3人,当玩家当i\ge334时,玩家1绝对不会输钱,这个时候总共有C_{999-i}^2种组合,此时期望为
E[i] = \frac{i*C_{999-i}^2}{C_{999}^3}
当i<334时,这个时候玩家1可能需要接龙,这个时候,其余两个玩家分配的金钱至少为i。这个时候,又分如下3种情况

玩家2和玩家3的钱都比玩家1多

这个时候可以作如下思路的转换:

因此可知,这种情况总共有C_{999-i*3}^2种,发生概率为:
loseRate(i) = \frac{C_{999-i*3}^2}{C_{999-i}^2}

其余两个玩家中其中一个玩家的钱跟第一个玩家一样,另一个玩家的金钱比这两个玩家要多

这个时候,玩家1有一半概率需要接龙。

假设是玩家2的金钱与玩家1相等,算出的结果乘以2即可,作如下思路的转换

因此可知,这种情况总共有C_{999-i*3}^1*2种,发生概率为:
1v1Rate(i) = \frac{C_{999-i*3}^1}{C_{999-i}^2}

3个玩家的金钱都一样

这个时候只有1种可能,玩家1有1/3的概率需要接龙,发生的概率为:
1v1v1Rate(i) = \frac{1}{C_{999-i}^2}

一定不需要接龙的情况

分析了上面3种情况之后,最后就是一定不需要接龙的可能,其概率为:
winRate(i) = 1 - loseRate(i) - 1v1Rate(i) - 1v1v1Rate(i)

接龙的话,赢钱为i-1000,可以求出期望为:
E[i]=loseRate(i)*(i-1000)+winRate(i)*i+1v1Rate(i)*i/2+1v1Rate(i)*(i-1000)/2+1v1v1Rate(i)*i*2/3+1v1v1Rate(i)*(i-1000)/3
当然,除了接龙之外,还有抽到特定金额就赢钱的情况,这个时候在作特殊处理即可。

将所有的E[i]求和即可得到赢钱的期望,需要注意的是由于其余3人至少获得1分,所以i最大为997

代码实现(swift)

func combinations(_ top:Int,bottom:Int)->Int{
    var res = 1
    for i in 1...top{
        res *= bottom + 1 - i
        res /= i
    }
    return res
}

let maxCount = combinations(3, bottom: 999)
var validCount = 0
var Expectation = 0.0
for i in 1...997{
    var money = Double(i)
    switch i{
    case 111:
        money += 1110
    case 123:
        money += 1230
    case 222:
        money += 1333
    case 234:
        money += 2340
    case 333:
        money += 2220
    case 456:
        money += 1666
    case 567:
        money += 1888
    case 678:
        money += 4000
    case 777:
        money += 4000
    case 789:
        money += 4000
    case 888:
        money += 8880
    default:
        break
    }
    if(i>=334){
        Expectation += money*Double(combinations(2, bottom: 999-i))/Double(maxCount)
        continue
    }
    
    let loseCount = Double(combinations(2,bottom:999 - i*3))
    let oneVSOneCount = Double(999 - i*3)*2
    let oneVSOneVSOneCount =  1.0

    let loseRate = loseCount/Double(maxCount)
    let oneVSOneRate = oneVSOneCount/Double(maxCount)
    let oneVSOneVSOneRate = oneVSOneVSOneCount/Double(maxCount)
    let winRate = (Double(combinations(2, bottom: 999-i)) - loseCount - oneVSOneCount - oneVSOneVSOneCount)/Double(maxCount)
    Expectation += loseRate*(money-1000)+winRate*money + 1.0/2*oneVSOneRate*money + 1.0/2*oneVSOneRate*(money-1000) + 1.0/3*oneVSOneVSOneRate*(money-1000) + 2.0/3*oneVSOneVSOneRate*money
}
print("E=\(Expectation)" )

运行结果

最后的结果为E = -63.09,也就是说玩家1平均每抢一次红包都会损失0.63元

如果忽略规则2(即把switch这段代码注释掉),则最后的结果为E = -0.8333,即E=-\frac{5}{6},由此可以看出上述求解过程还是有优化的空间的。

上一篇 下一篇

猜你喜欢

热点阅读