• 黄金点游戏编程总结


    作业要求博客链接: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)。最后发现人心不可测啊,还是强化学习好。

  • 相关阅读:
    【u244】山地考察
    【u246】卫星照片
    【z08】乌龟棋
    【22.95%】【hdu 5992】Finding Hotels
    【t048】水流
    【b601】能量项链
    【b702】字符串的展开
    【a903】石子归并
    【9915】乘积最大
    JavaEE(24)
  • 原文地址:https://www.cnblogs.com/zhiqilin/p/9827474.html
Copyright © 2020-2023  润新知