黃金點遊戲程式設計總結
黃金點遊戲程式碼倉庫地址為: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)。最後發現人心不可測啊,還是強化學習好。