黄金点游戏编程总结

作业要求博客链接:https://edu.cnblogs.com/campus/ustc/InnovatingLeadersClass/homework/2231

黄金点游戏代码仓库地址为:https://dev.azure.com/v-zhilin/_git/GoldPoint

项目估计时间

由于这个项目非常简单,基本上一个小时就可以编写完成,因此如果事先使用PSP表格来对项目进行规划,反而会拖延项目完成的时间。在这个项目中,我认为PSP不需要使用。

接口设计

首先我们将整个软件架构分为3块,第一块为交互模块,这个模块的任务主要负责和比赛程序的输入输出进行交互,并将获得的数据预处理后发送给第二个模块;第二个模块为策略模块,这个模块主要实现一些策略,这些策略能根据给定的预处理数据来预测下一次黄金点的值;第三个模块为控制模块,主要负责协调交互模块和策略模块之间的工作。下面分别介绍这三个模块:

交互模块

  • 主要文件为:data.py

  • 主要函数:Data.observe()

  • 主要函数功能描述:读取标准输入流的数据格式,通过 numpy 的矩阵变换获得两个输出:

    • 黄金点历史信息:g_history:这是一个1维的 ndarray,记录了从第一轮开始到当前轮的所有黄金点值(ground truth)
    • 各队提交历史信息:team_history:这是一个3维 ndarray :记录了从第一轮开始到当前轮每个队的提交信息,其中第一维表示队伍的编号,第二维表示对应的轮数,第三维表示提交的第一个数和第二个数.

策略模块

  • 主要文件为:policy.py

  • 成员函数:

    成员函数名成员函数功能

    Policy.__init__

    (game_iter, team_num)

    设定策略模块的基本信息:游戏进行的轮数,

    队伍的数量,各个策略的全局参数

    Policy.__basic__average(arr) 平均策略,获得当前给定队列的平均值点

    Policy.moving_avg

    ( g_history, team_history)

    滑动平均策略,根据给定的历史黄金点信息,

    通过滑动平均预测下一个黄金点的信息,

    对Policy.__moving_avg__(arr) 的一次封装

    Policy.__check_fluct__

    (g_history)

    检测黄金点的波动,返回最近check_window

    次内黄金点的波动范围

    Policy.moving_exp_avg

    ( g_history, team_history)

    指数滑动平均策略,根据给定的历史黄金点信息,

    通过指数滑动平均预测下一个黄金点的信息

    Policy.__detect_fluct__

    (g_history, team_history)

    检测其他队伍干扰的情况,根据每个队伍的输入和

    黄金点的偏差,如果这个偏差大于一定的值,我们

    认为这个队伍会对黄金点进行干扰,当我们采取干

    扰策略时,我们的目标是制造干扰,但同时也不想

    因为干扰造成失分,因此这个函数会返回一个干扰

    队伍产生干扰的平均值,当我们进行干扰时,干扰

    值会选择小于这个值进行扰动

    [此函数在第二轮比赛中已经废弃]

    Policy.random_fluctuation

    (pred, max_bias, exp_mea)

    这个函数在第二轮比赛中已经进行了修改:当检测

    到黄金值在最近几轮中稳定时(波动范围小于2),

    我们采取扰动策略,根据滑动平均的预测值基础上,

    随机增加10-40作为一个干扰值,并根据这个干扰值

    重新调整我们自身的滑动平均预测值;如果黄金点在

    最近几轮中波动较大(大于2),说明有队伍在进行

    干扰,那么我们采取的措施是通过提交滑动平均,

    指数滑动平均两个值进行预测。结果返回所要提交的两个数

    Policy.predict

    (g_history, team_history)

    这个函数作为外部模块(控制模块)调用本模块时的接

    口,基于以上的策略进行组合输出最终提交的两个数字

控制模块

  • 主要文件: get_numbers.py
  • 没有成员函数,主要功能为衔接交互模块和策略块,进行最终提交。

异常处理

由于本次编程内容非常简单,而且设计处理的数据量非常小,代码编程过程中不会有引发异常的情况,因此不做对异常处理的实现。

合作方式

本次合作方式,主要为:两人先一起协商策略,我(林郅琦)负责代码编写的实验测试,邢宇负责代码复审。在第一轮比赛结束后,代码调整的半小时里,我(林郅琦)主要负责代码编写和实验验证,邢宇负责想法的提出和策略的阈值评估。

自我评价

  • 优点:

    • 编程速度快
    • numpy 向量化接口非常熟悉
    • 对代码的细节能够做到较好处理
  • 缺点:

    • 想法较为简单,有点鲁莽

队友评价

  • 优点:

    • 想法较好(尤其体现在第一轮结束后对代码的调整上)
    • 复审仔细
    • 快速的找到策略的阈值,尤其是在第一轮比赛吃完饭后,只有半小时的调整时间里,能很快确定判定波动大小的阈值。
  • 缺点:

    • 参与代码编写的工作不是很多(主要是因为我把一不小心就写完了全部的代码)

合作照片

 

实际花费时间

第一轮比赛前

流程花费时间
方案制定 5min
代码编写 40min
代码复审 20min
组合测试(与代码复审同时进行) 20min
结果分析 10min
总共耗时 1h 15min

第一轮至第二轮比赛间

流程花费时间
方案制定及上一轮数据分析 10min
代码编写 15min
组合测试 5min

实际上第二轮的时候,方案制定->代码编写->组合测试 是一个循环过程,上面的表格为总体的每个项目所花费的时间。

比赛感悟

在第一轮比赛的时候,我们队很稳的拿到了倒数第一名(13/13),但实际上,在比赛前给的夏令营赛季复盘数据中,我们的代码能稳定的跑在第一名,究其原因,是因为夏令营的数据收敛了,这导致我们的扰动策略大获成功,而在现场的比赛中,由于许多队伍都进行的干扰,G点一直处在4-6的波动范围内,所以导致比赛过程中预测出现重大失误。同时在夏令营的数据上,指数滑动平均的表现远远好于滑动平均的表现,而在现场第一轮比赛的复盘数据中,我们发现,使用滑动平均反而优于指数滑动平均,而且采用指数滑动平均配合滑动平均(少干扰)的策略能让我们在现场第一轮复盘数据上稳定达到第一名,于是我们决定在第二轮采用这样的策略,最后比赛成果为第三名(3/13)。最后发现人心不可测啊,还是强化学习好。

posted @ 2018-10-21 22:45  zhiqilin  阅读(533)  评论(2编辑  收藏  举报