黄金点游戏Bot
Bot8前来报道
1.问题定义
a) 问题描述
- N个玩家,每人写一个0~100之间的有理数 (不包括0或100),提交给服务器,服务器在当前回合结束时算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值。 提交的数字最靠近G(取绝对值)的玩家得到N分,离G最远的玩家得到-2分,其他玩家得0分。 只有一个玩家参与时不得分。
b) 简单的思考
- 拿到这个问题想的是如果大家都不冒险的话,那么结果会无限接近0
- 所以显然要有扰动来使游戏变得更有趣,而且扰动很关键(这里扰动指输出显然不正确的值使黄金点偏移)
- 我们要做的就是预测下一轮的黄金点
2.方法建模
a) 环境分析
- 经过在Room 1和几个bot简单的较量,可以发现黄金点变化的十分剧烈,这使精准预测的难度的大大提高
- 由于变化剧烈,所以考虑前100个或者10个黄金点显得没有道理,所以应该考虑更少的黄金点,最多5个足够了(最后我们只用最后2个的差)
- 在考虑数据的时候,显然小的数据的细微变化的价值要大于大的数据的剧烈变化,所以应该有适当的针对措施(比如小值细分,大值粗分)
- 对于扰动,向上扰动(50-100)效果明显,而向下扰动(输出0)效果不明显,很容易被截胡,所以扰动应该只向上扰动
- 连续扰动其实效果不大,因为会有其他人的策略很快适应这个环境
b) 选择模型
- 根据助教的提示,我们在非机器学习算法、Q-learning、DQN直接进行对比,尝试选出合适的策略
- 首先尝试干扰策略,干扰的目的是干扰其他机器学习算法模型的正确学习,具体策略有每20回合连续干扰10回合,每10回合连续干扰5回合,每回合都干扰,不干扰,随机泊松分布连续干扰
- 干扰同时要预测在干扰下的黄金点,这里我们假设其他人不干扰,得到黄金点的值
- 基于之前的环境分析,我们可以知道状态不需要存储很多前面的数字,这样最近的黄金点的特性如何提取成我们的状态表示是一个核心问题
- 由于数字较少,特性较少,所以我们认为DQN的作用不会太大,反而会影响模型训练速度
- 我们最后考虑Q-learning
- 剩下的就是action了,首先要有上一个黄金点,上一个黄金点*0.618,然后还要尝试截胡其他人的干扰
c) Q-learning简介
- 类似于动态规划,有状态和状态转移,在状态转移时会有得分产生,我们的目标就是学出一个状态转移表。
- 想学出来的话需要有action的反馈,让我们知道下次遇到这个状态时倾向于使用哪个action。
- 具体公式:
NewValue = CurrentValue + lr * [Reward + discount_rate * (highestValue between possible actions from the new state s’) — CurrentValue]
d) 实现细节
- 预先训练好model,提前加载,并即时存下model
- 经过测试,干扰选择随机概率干扰,而且上回合如果干扰过了,这回合要抑制干扰,如果一直没干扰要提升干扰概率
- 在Q-learning中去除自己干扰回合的黄金点,使model尽快成型
- 状态表示这里只考虑上个黄金点和当前黄金点的差值,通过放大小区间,缩小大区间来转换为100个状态(原因在环境分析里有说)
- 行动策略除了上个黄金点,上个黄金点*0.618,截胡干扰之外还要加入上下浮动(开始用0.001,最后用0.011,其实只要比其他bot多一点或者少一点就好了)
e) 工作流程
- 用Q-learning预测action,得到两个数字
- 判定本回合是否干扰,具体分4个干扰阶段,每个阶段有概率(0.05, 0.2, 0.4, 0.7)干扰,每回合若未干扰有0.9概率转移下个阶段,若干扰则阶段清零(即变为0.05概率干扰的阶段)
- 若干扰,用(50-100)的随机数替换number2,同时在假定其他人不干扰的情况下估计出新的number1
3.结果分析
a) 两轮得分
第一轮1690分(1000轮)
第二轮13850分(10000轮)
b) 心得反思
两轮第一还是超出预期的,没想到效果还不错 v
其实在交bot之前,我们也是用自己的bot在自己的房间中pk,在多轮中效果最好的作为最终的bot
如果将每轮提交的数字变成3个,只需改变action即可工作,不过model的效果和训练时间有待考究
若有更多的参赛者,可能要重新考虑干扰为我们带来的收益
强行三明治的话,就要怪队友CHF太强了,完全不需要我的发挥,我躺好了(咸鱼的姿势),溜了溜了