在入门强化学习的时候遇到了这样一个问题:假如你是HR,前来面试秘书的十名面试者能力指数分别为1-10,要求你在前k名面试者中不做出选择,从第k+1名面试者开始,若有面试者的能力指数高于前k名,则录用。另外,对于后面的面试者,你必须当场给出录用结果,否则面试者不会回来。求为使录用的秘书能力指数最高,k应定为何值?
这个问题对应着强化学习的exploration-exploitation思想。HR经验不足,需要先在前k名面试者中有一个exploration过程,才能知道自己要找什么样的秘书。但又不能把太多面试者都pass掉,否则后面的可选择性太小,exploitation过程收益小。
所以一定对应着这样一个k值,使得exploration效果既不会太差,后面exploitation收益也不会很小,既录用秘书能力指数的均值最大。
有更为清晰的数学证明:
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()
结果如图
但是有个很严重的问题,我们发现最优值并不在理论值≈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值的文章,这个问题只能等等喽