说实话看到这道题我时,我也懵了一下,恍惚间感觉自己已经脱离了程序员的世界,这种算法题我还是第一次看到。先贴上题

10个小球,随机分到12个盒子里,求恰好10个盒子都为空的概率。要求用Python程序模拟十万次,暴力求出该概率。

对于这套题的解法,在这篇文章中已经说的很清楚了,我在这里也仅仅是对其进行简单的转述。
题目中要求采用暴力法,意味着需要采用蒙特卡洛模拟法。如果采用手算的方法,结果是有意思的字节面试题 - 图1
这是一个较小的概率,而题目要求通过模拟十万次,这意味着可能十万次都不一定会出现一次十个盒子都为空的情况。具体的代码如下

  1. import random
  2. total_number = 100000
  3. def simulation(balls = 10, boxes = [0] * 12):
  4. for i in range(balls):
  5. index = random.randint(0, 11)
  6. boxes[index] += 1
  7. return boxes
  8. def emptyBoxes(boxes):
  9. number = 0
  10. for item in boxes:
  11. if item == 0:
  12. number += 1
  13. return number
  14. def simulations(number):
  15. ten_empty_boxes = 0
  16. for i in range(number):
  17. result = simulation(10, [0] * 12)
  18. if emptyBoxes(result) == 10:
  19. ten_empty_boxes += 1
  20. return float(ten_empty_boxes)/total_number
  21. print(simulation(total_number))

用这个代码我运行了三次,每次结果都是0.0

那么如何仅仅通过十万次就计算出正确的结果呢,下面便是这篇文章中给出的解法
我们先假设两个事件:
第一种情况,我们称之为A,A表示十个球放到十二个盒子中,令其中十个盒子都是空的
第二种情况,我们称之为B,B表示十个球中的五个随机放入到十二个盒子中,令十个及十个以上的盒子为空。
那么在A发生的情况下,B肯定是发生的,用公式表示便为有意思的字节面试题 - 图2,那么根据条件概率公式可以得到有意思的字节面试题 - 图3
由于P(B) 和P(A|B)的概率要远大于P(A)的概率,因此通过计算这两者的值来最终得到目标值,所以接下来通过BF来求这两者的值

  1. def simulations_part1(number):
  2. five_empty_boxes = 0
  3. states = []
  4. for i in range(number):
  5. result = simulation(5, [0] * 12)
  6. if emptyBoxes(result) >= 10:
  7. five_empty_boxes += 1
  8. states.append(result)
  9. return float(five_emtpy_boxes)/number, states
  10. prob_part1, states_part1 = simulations_part1(10000)
  11. print(prob_part1)

得到结果:0.0078

  1. def simulations_part2(number, states):
  2. ten_empty_boxes = 0
  3. for i in range(number):
  4. index = random.randint(0, len(states) - 1)
  5. state = states[index][:]
  6. result = simulation(5, state)
  7. if emptyBoxes(result) == 10:
  8. ten_empty_boxes += 1
  9. return float(ten_empty_boxes)/number
  10. prob_part2 = simulations_part2(90000, states_part1)
  11. print(prob_part2)

得到结果:0.00013333333333333334
两个值都计算完后,相乘得到最终的结果

  1. print(prob_part1 * prob_part2)

最终结果:1.04e-06

所以看到没,这道题其实考察的是对于条件概率公式灵活应用。

参考资料

https://www.nowcoder.com/discuss/395924
https://medium.com/@data.scientist/solving-the-interesting-bytedance-interview-question-bb30b31cdf5