聘秘书问题(没完全解决)

在入门强化学习的时候遇到了这样一个问题:假如你是HR,前来面试秘书的十名面试者能力指数分别为1-10,要求你在前k名面试者中不做出选择,从第k+1名面试者开始,若有面试者的能力指数高于前k名,则录用。另外,对于后面的面试者,你必须当场给出录用结果,否则面试者不会回来。求为使录用的秘书能力指数最高,k应定为何值?

这个问题对应着强化学习的exploration-exploitation思想。HR经验不足,需要先在前k名面试者中有一个exploration过程,才能知道自己要找什么样的秘书。但又不能把太多面试者都pass掉,否则后面的可选择性太小,exploitation过程收益小。

所以一定对应着这样一个k值,使得exploration效果既不会太差,后面exploitation收益也不会很小,既录用秘书能力指数的均值最大。

有更为清晰的数学证明:

https://blog.csdn.net/cotxyz/article/details/8294921?fromshare=blogdetail&sharetype=blogdetail&sharerId=8294921&sharerefer=PC&sharesource=2302_79485806&sharefrom=from_linkicon-default.png?t=O83Ahttps://blog.csdn.net/cotxyz/article/details/8294921?fromshare=blogdetail&sharetype=blogdetail&sharerId=8294921&sharerefer=PC&sharesource=2302_79485806&sharefrom=from_link在这里我们使用python程序模拟出最优k值 

import random
import numpy as np
import matplotlib.pyplot as plt

# 定义好他们的分数
score = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 空列表用于存储每个k值对应的能力指数均值
y = []
# 遍历每个k值情况
for k in range(9):
    # 每次遍历开始都使总指数为0
    total_score = 0
    # 对每个k值进行大量模拟
    for _ in range(10000):
        # 每次面试都是乱序上场
        random.shuffle(score)
        # 从k+1个人开始比较
        for candidate in range(k + 1, 10):
            # 分值高就记下来并跳出该循环,开始下一次模拟
            if score[candidate] > max(score[:k+1]) or candidate == 9:
                total_score += score[candidate]
                break
    # 把该k值模拟出的均值添加到列表y中,开始模拟下一k值
    y.append(total_score/10000)
# 输出所有k值对应结果
print(y)
# 简单绘图
k = np.arange(1, 10)
plt.figure()
plt.xlim(1, 9)
plt.plot(k, y, marker='o')
plt.show()

结果如图

但是有个很严重的问题,我们发现最优值并不在理论值\frac{n}{e}≈3.6附近取到(左右还有三和四呢,怎么模拟出2了)于是怀疑是轮数太少,于是加大至10^6轮(不知道为啥从七次方以上就一直训练不出来了)

结果依然差强人意

思来想去不知道应该改进哪里,于是动用AI写了一段

import random
import numpy as np
import matplotlib.pyplot as plt

# 定义面试者的优秀指数
score = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = []

# 模拟次数
simulations = 10000

# 计算每个k值下的平均录用优秀指数
for k in range(9):
    value = 0
    for _ in range(simulations):
        random.shuffle(score)
        # 从第k+1个开始寻找第一个比前k个更优秀的候选人
        for j in range(k + 1, 10):
            if score[j] > max(score[:k + 1]):
                value += score[j]
                break
        else:
            # 如果没有找到更好的,则选择最后一个
            value += score[-1]

    y.append(value / simulations)

# 打印结果
print(y)

# 生成与y长度相同的k值数组
k = np.arange(1, 10)  # 生成从1到10的整数数组

# 绘制图表
plt.figure()
plt.plot(k, y, marker='o', linestyle='-', color='b')
plt.xlabel('k')
plt.ylabel('Average Score of Selected Candidate')
plt.title('Average Score of Selected Candidate vs. k')
plt.grid(True)

# 添加最优k值的标记
best_k = k[np.argmax(y)]
best_score = max(y)
plt.annotate(f'Best k: {best_k}, Score: {best_score:.2f}',
             xy=(best_k, best_score),
             xytext=(best_k, best_score + 0.5),
             arrowprops=dict(facecolor='black', shrink=0.05))

# 显示图表
plt.show()

显然AI写的更有py风格,博主写的一股C语言味道。

但有趣的是,即使是AI的代码模拟的最佳值仍为2

但也没有找到其他模拟k值的文章,这个问题只能等等喽

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值