華為codecraft2018總結


華為codecraft2018總結

 

想來也是參加了第二次了,自己還是那么的菜。總結下今年的比賽,得獎是不存在的了,但是收獲還是有的。

代碼相關的都在這里了:https://github.com/huipengly/CodeCraft-2018-ecs

 

一、賽題

為了防止明年賽題官網更新,這里我傳一份在網盤。

鏈接: https://pan.baidu.com/s/1C--5XEtVQq3LJQXWq_4yXw 密碼: z5mc

 

二、賽題分析

首先,官方不讓用第三方庫了(上一年沒參加,但是也是不讓用了)。我參加的第一年,大家用庫用的太瘋狂了,不是編程大賽了。真是苦了python選手。

今年的賽題主要分為兩個方面,第一是對flavor數量的預測。第二是對預測結果進行分配。

 

預測方面,這是一個時間序列預測的問題。數據中體現的特征有歷史銷量數據和flavor的型號參數。這里,我認為有助於預測的特征信息有1.flavor的cpu/mem比例。2.日期中的周末,節假日。從官方的給出的數據例子中,可以看出,節假日和周末的購買量明顯的小。這兩點看出來了,但是不知道怎么用,很無奈。

裝箱方面,官方這里有一個小坑。賽題里提到了優化方向有cpu和mem兩種,只需要將其中所需要的一個優化到最小。但是去仔細推導一下,由於系統不允許物理機資源超分,無論要求那個優化方向,只需要將總物理機數目優化到最小即可。所以裝箱對整個賽題分數的影響較小,最重要的還是預測。

 

三、解題思路

3.1數據預測

數據預測用了挺多方法的,越做分越低(心疼自己)。

1.線性自回歸(AR)

最簡單的一個方法。初賽指導思路上給到的預測思路就是這個。這是統計學里做時間序列預測最簡單的方法。AR方法認為,下一時刻的數據與之前n個時刻的數據是線性相關的,只是與每個時刻相關性不同,需要乘一個系數。最后的公式如下。3.3.2為矩陣形式,具體為3.3.3式。這里Xp是p時刻的數據。

 

 

知道形式之后,有兩個問題需要確定,第一是之前p個時刻相關,這個p如何確定。第二是在確定p后,每個時刻的系數如何確定。

對於問題一,我沒有學會,比賽代碼中的階數是隨便試的。哎,數學能力太差。懷念本科做比賽只用寫代碼的日子。

對於問題二,一般使用的就是最小二乘法。預測做不到准確無誤,最小二乘法就是尋找一個式3.3.2中的a,使得式子的誤差最小。對於矩陣有求解公式,具體的推導可以看這篇博文https://blog.csdn.net/monsterhoho/article/details/46753673

目標函數:

解:

當階數p定的不好時,可能會不可逆。我的做法是,不可逆就降低階數。

這個方法是一開始就實現了的。結果是分最高的,賊氣,雖然也就68分。

2.神經網絡

本科做數模,神經網絡對於我就是一個工具箱,把數據導進去就好了。也不懂輸出的是個啥,為啥這么輸出。這次算是把全連接網絡和bp(反向傳播)看懂了。本應在上學期上課學會的。想出這個方法的人真牛逼。具體講解、推導可以看這個。

https://www.zybuluo.com/hanbingtao/note/476663

然后就是c++實現,寫了兩天,沒寫出來,真丟人。一定程度上說明自己沒有完全看透這個算法。然后用了別人的代碼,跑了起來。

三層神經網絡,第一層輸入層,輸入預測前三天的數據。第二層隱層,4個節點。第三層輸出層,輸出預測結果。梯度下降方法沒看代碼,不清楚。學習率0.5。

輸入數據做了縮放處理,將所有歷史數據縮放為0-1的數。歷史數據中最大的數據為1,最小為0.

最后結果是60-65吧。

3.自回歸滑動平均模型(ARMA)

在線性自回歸中加入了對誤差的使用。具體做法是,首先用比較高的階數進行一次ar,會得到一個預測結果和預測誤差,這里的預測誤差就是MA所用到的誤差值。第二部,使用誤差來做arma。預測方法還是最小二乘法。簡要的如下圖。

 

 

 具體的講解可以看這三個pdf,把ar、ma、arma講的很清楚。分數50多。

4.還是arma,但是有新想法

在這個時候,看了別人做天池,鹽城車牌上牌量的比賽,我有了一個新的想法。這里我們需要預測幾個flavor,把flavor整體先加起來,預測整體的數據,再將整體預測的數據拆分到每一個flavor。這樣做的好處是讓每天的數值更大,之前每個flavor時,數據比較稀疏,有較多的天數沒有數據,我認為是不利於預測的。但是這樣也有一個很大很大的壞處,最后沒有很好的拆分想法,結果還是不理想。

總體預測。然后按照總的/最后30天的/最后7天的比例拆分,分數很低,而且是個下降的趨勢。

把數據按照7天/3天先平均一下,分數更低。

加一點點隨機值后,能夠把分數提到69。改了評分bug之后,始終上不去70。

3.2預測結果裝箱

由於上學期學習了智能優化方法,自己寫過遺傳算法的代碼,所以決定使用遺傳算法。遺傳算法是一種啟發式算法,通過模仿生物進化的優勝劣汰來巡游,並且有一定的跳出局部最優的能力。具體遺傳算法的內容可以去網上搜,很多資料。這里講主要思想。

遺傳算法染色體編碼有很多種,這里使用順序編碼,按照1-n的自然數進行編碼,每個自然數出現且只出現一次。

染色體解碼,首先將預測出的n個flavor按照1-n的自然數進行編號。染色體會是這n個編碼的排列,例如預測了5個flavor,染色體可能是1|3|2|5|4,按照從前往后的順序放入物理機,當物理機被裝滿時,向下一個物理機放置。直到染色體被放置完,完成染色體解碼。

染色體交叉,這里我使用了ox的方式。可以看這個網站了解染色體交叉的信息。https://blog.csdn.net/u012750702/article/details/54563515。使用輪盤賭的方式選擇交叉的染色體。輪盤賭可以看這個網站:https://www.cnblogs.com/adelaide/articles/5679475.html

我測試的分配的速度、結果都不錯。

 

四、結果

渣渣效果,我覺得時預測階段沒做好。還是自己數學能力太弱了,滿腦子都是編程。最后測試用例300分,就拿了220分。

 

寫這個博客紀念一下這個比賽吧,雖然自己很菜。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM