回复: 10
收起左侧

Optiver 赛马问题如何准备

本楼:   👍  1
100%
0%
0   👎
全局:   88
81%
19%
20

2023(10-12月) 金工类 博士 全职@optiver - 网上海投 - 技术电面  | 😐 Neutral 😐 AverageOther | 应届毕业生
看到optiver赛马问题。假如有4匹马,能力为a,b,c,d,随机分组淘汰赛。每一句胜率与能力正比,比如a和b比赛,a的胜率就是a/(a+b). 要求快速计算或估算某一匹马胜率。

想凭直觉估算,精确求解是不可能的。我们不妨简化问题:先normalize到a=1,a马的胜率和mean(b,c,d), std(b,c,d) 有何关系?

import numpy as np
import matplotlib.pyplot as plt
def calculate_analytical_prob(a, b, c, d):
    P_subcase_1a = (a / (a + b)) * (c / (c + d)) * (a / (a + c))
    P_subcase_1b = (a / (a + b)) * (d / (c + d)) * (a / (a + d))
    P_subcase_2a = (a / (a + c)) * (b / (b + d)) * (a / (a + b))
    P_subcase_2b = (a / (a + c)) * (d / (b + d)) * (a / (a + d))
    P_subcase_3a = (a / (a + d)) * (b / (b + c)) * (a / (a + b))
    P_subcase_3b = (a / (a + d)) * (c / (b + c)) * (a / (a + c))
    return (1/3) * (P_subcase_1a + P_subcase_1b + P_subcase_2a + P_subcase_2b + P_subcase_3a + P_subcase_3b)
# Set a = 1 and simulate 10,000 random pickings of b, c, d from uniform(0,2)
a = 1
n_simulations = 10000
avg_ratios = []
square_ratios = []
std_ratios = []
winning_rates = []
for _ in range(n_simulations):
    b, c, d = np.random.uniform(0, 2, 3)
    avg_ratio = np.mean([b, c, d]) / a
    square_ratio = np.mean([b**2,c**2,d**2])**.5
    std_ratio = np.std([b, c, d]) / a
    prob_a_wins = calculate_analytical_prob(a, b, c, d)
    square_ratios.append(square_ratio)
    avg_ratios.append(avg_ratio)
    std_ratios.append(std_ratio)
    winning_rates.append(prob_a_wins)
# Create a 2D histogram plot
plt.figure(figsize=(10, 6))
plt.scatter(avg_ratios, std_ratios, c=winning_rates, cmap='viridis', marker='o', s=10)
plt.colorbar(label='Winning Rate of a')
plt.xlabel('avg(b, c, d) / a')
plt.ylabel('std(b, c, d) / a')
plt.title('Winning Rate of a vs. avg(b, c, d) / a and std(b, c, d) / a')
plt.grid(True)
plt.show()

可以看到,胜率和mean(b,c,d) 非常相关,但是和std关系不大:

想一想,winning prob 大致会和mean是什么关系呢?
如果b=c=d=1,不难计算,winning rate = 1/4, 首先猜想1/(1+b+c+d)并画图
可以看到correlation非常明显,但线还不是很直。

根据mean(b+c+d)--> 0 or inf求极限,不难得到另一个猜想,并画winning prob VS 1/(1+mean)^2

这就非常直了。改变simulate时bcd的分布,可以自行总结近似公式:
当mean(b,c,d)>1时,p(a win) = 1/(1+mean)^2

当mean(b,c,d)<1时,p(a win) = 1/(1+mean)^2 * (1- 0.06*std/mean)

对于8匹马的情况,同样先写代码观察:
import itertools


def calculate_8_player_win_rate(a, *other_players):
    other_players = list(other_players)
    win_prob = 0
    # Generate all combinations of 3 players to pair with 'a'
    for subgroup in itertools.combinations(other_players, 3):
        # Calculate the probability that 'a' wins in its group of 4
        a_group_prob = calculate_analytical_prob(a, *subgroup)
        # The remaining 4 players are in the other group
        remaining_players = [p for p in other_players if p not in subgroup]
        # Calculate probability that 'a' wins against each possible winner from the other group
        for player in remaining_players:
            # Probability that this player wins the other group
            other_group_prob = calculate_analytical_prob(player, *[p for p in remaining_players if p != player])
            # Probability that 'a' wins against this player
            a_vs_player_prob = a / (a + player)
            # Add to the total win probability for 'a'
            win_prob += a_group_prob * other_group_prob * a_vs_player_prob
    return win_prob / len(list(itertools.combinations(other_players, 3)))

写完记得simulate10000场游戏验证simulation和analytical计算的概率是否一致
您好!
本帖隐藏的内容需要积分高于 188 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 188 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
.., h
        b, c, d, e, f, g, h = generate_scaled_players(mean, std)
        # Calculate mean and std of the scaled abilities
        actual_mean = np.mean([b, c, d, e, f, g, h])
        actual_std = np.std([b, c, d, e, f, g, h])
        # Calculate guess
        guess = 1 / (1 + actual_mean)**3
        # Calculate analytical win rate
        win_rate = calculate_8_player_win_rate(a, b, c, d, e, f, g, h)
        # Calculate deviation
        deviation = 1 - win_rate / guess
        # Keep track of the values
        means.append(actual_mean)
        stds.append(actual_std)
        guesses.append(guess)
        win_rates.append(win_rate)
        deviations.append(deviation)
    return means, stds, guesses, win_rates, deviations
# Run the simulation
means, stds, guesses, win_rates, deviations = simulate_combination_stats()


自行总结近似公式:
当mean>1时,p(a win) = 1/(1+mean)^3
当mean<1时,p(a win) = 1/(1+mean)^3 * (1-0.15*std/mean)

本帖子中包含更多资源

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x

评分

参与人数 3大米 +12 收起 理由
小亩_c61ce1d + 1 赞一个
亦凡 + 1 赞一个
清道神君 + 10 欢迎分享你知道的情况,会给更多大米奖励!

查看全部评分


上一篇:Garda Capital SDE Summer Internship
下一篇:Optiver Intern OA
finnshing 2024-9-9 08:49:12 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   520
97%
3%
18
  1. def win_prob(a, b):
  2.     return a / (a + b)

  3. def three_horse_win_prob(a, b, c):
  4.     return win_prob(a, b) * win_prob(a, c) + win_prob(a, c) * win_prob(a, b)

  5. def four_horse_win_prob(a, b, c, d):
  6.     prob_abcd = win_prob(a, b) * three_horse_win_prob(a, c, d)
  7.     prob_acbd = win_prob(a, c) * three_horse_win_prob(a, b, d)
  8.     prob_adbc = win_prob(a, d) * three_horse_win_prob(a, b, c)
  9.     return prob_abcd + prob_acbd + prob_adbc
复制代码
回复

使用道具 举报

 楼主| Nostalgib_ 2024-9-10 01:52:03 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   88
81%
19%
20
补充一下:在8匹马的情况,当winning rate<0.02时,p(a win) = 1/(1+mean)^3 * (1+0.1*std/mean)

本帖子中包含更多资源

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
扫码关注一亩三分地求职移民公众号
更多干货内容等你发现
回复

使用道具 举报

 楼主| Nostalgib_ 2024-9-10 04:23:07 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   88
81%
19%
20
本帖最后由 Nostalgib_ 于 2024-9-9 16:27 编辑

Curve fit 了一下8匹马的情况,用了如下公式:

注意:np.log以e为底,也就是ln
其中x1为上述所描述的guess, x2 = log(x1), x3 = std/mean, y为真实的win rate

得到最优解
delta = 0.15, mid = 0.034, scale = 0.76
但是临场手撕tanh计算显然是不可能的,所以记住楼上的经验公式就可以了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
回复

使用道具 举报

lllxxy 2024-9-16 07:41:43 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   2
100%
0%
0
请问这是哪个岗位的哪一轮会考的题啊,目前我收到的是QR的OA,谢谢
回复

使用道具 举报

地里匿名用户
匿名用户-5LJGB  2024-9-21 22:53:37
本楼:   👍  0
0%
0%
0   👎
请问赛马是intern还是全职的题呀
回复

使用道具 举报

lllxxy 2024-9-24 01:55:13 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   2
100%
0%
0

三匹马的时候漏掉了B和C先跑的情况吧,以及从三匹马开始,你都忘了乘以一个概率。
回复

使用道具 举报

lllxxy 2024-9-24 01:57:04 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   2
100%
0%
0

def win_prob(a, b):     
    return a / (a + b)   

def three_horse_win_prob(a, b, c):
    return (win_prob(a, b) * win_prob(a, c) + win_prob(a, c) * win_prob(a, b) + win_prob(b, c) * win_prob(a, b) + win_prob(c, b) * win_prob(a, c)) / 3

def four_horse_win_prob(a, b, c, d):     
    prob_abcd = win_prob(a, b) * win_prob(c, d) * win_prob(a, c)  + win_prob(a, b) * win_prob(d, c) * win_prob(a, d)
    prob_acbd = win_prob(a, c) * win_prob(b, d) * win_prob(a, b)  + win_prob(a, c) * win_prob(d, b) * win_prob(a, d)
    prob_adbc = win_prob(a, d) * win_prob(b, c) * win_prob(a, b)  + win_prob(a, d) * win_prob(c, b) * win_prob(a, c)   
    return (prob_abcd + prob_acbd + prob_adbc)/3


# Example input: Abilities of the 4 horses
a, b, c, d = 1, 1, 1, 1
# Compute the winning probability for each horse
print(three_horse_win_prob(a, b, c))
print(four_horse_win_prob(a, b, c, d))
回复

使用道具 举报

finnshing 2024-9-24 04:01:08 | 显示全部楼层
本楼:   👍  0
0%
0%
0   👎
全局:   520
97%
3%
18
lllxxy 发表于 2024-9-23 17:55
三匹马的时候漏掉了B和C先跑的情况吧,以及从三匹马开始,你都忘了乘以一个概率。

那个是变量
回复

使用道具 举报

本楼:   👍  0
0%
0%
0   👎
全局:   6
100%
0%
0
谢谢分享~~~~~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

Advertisement
>
快速回复 返回顶部 返回列表