1. 程式人生 > >黃金點遊戲程式設計總結

黃金點遊戲程式設計總結

作業要求部落格連結: 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)。最後發現人心不可測啊,還是強化學習好。