2018年华为软件精英挑战赛整理

这里写图片描述
经历不到一个多月的辛苦,拿了个二等奖(10/64)和公司的免笔试和免技术面试绿卡,由于初赛都是自己在编,一个多月大部分精力都投入在比赛上,复赛阶段导师在催论文进度,实在不敢一直把精力放在这上面了,最后复赛只是写了一个能正确跑出结果的代码,但是实在没时间优化了,不过整个过程自己还是学到了许多东西,也还算比较欣慰了吧!
这里是赛题链接:http://codecraft.devcloud.huaweicloud.com/home/detail
废话不多数,直奔主题吧,下边写一点在在比赛过程中学习和了解到的一些优秀算法。
首先读完赛题可以了解到,本赛题实际上是分成两个部分“预测”问题和“资源优化”(放置)阶段,即根据各种不同规格的虚拟机的历史申请量,预测将来一段时间的各种规格虚拟机使用量,然后决定之后开启多少服务器来装这些虚拟机,在满足各种资源维度的约束下,达到各种资源(CPU和MEM)利用率最优的问题,下面就从两个方面介绍。

1.预测阶段

1)数据清洗阶段
首先对于大赛给的输入文件每种虚拟机进行每种虚拟机每天用量的统计,贴一个图感受一下(图找不到了,贴一张txt截图),下图每列对应虚拟机flavor1~flavor15某个月每一天的用量,如下:
这里写图片描述
这么多的0 。。。。。。。。(看到的第一眼是崩溃的,,)
不过没办法,硬着头皮搞吧,大致尝试了一些方法对于数据进行处理:
1.高斯滤波
实际上高斯滤波的原理就是用某个元素本身以及它邻域(邻域大小由高斯模板自己定)内元素的加权平均,代替这个元素的值,具体介绍可见下面两个博文:
https://blog.csdn.net/shanchuan2012/article/details/53071159
https://blog.csdn.net/u013007900/article/details/78181249
2.中值滤波
顾名思义,某个元素由其本身以及邻域内的元素排序后的中值对于某元素进行替换。
3.均值滤波
顾名思义,某个元素由其本身以及邻域内的元素均值值对于某元素进行替换。
以上三种处理方式多适用于图像处理,各有优缺点,介绍的博文很多,以及我的代码中也有相应实现(最后会贴上自己的github,有兴趣的可以瞄一眼,给个star,嘿嘿)
4.箱型线图
百度百科链接献上: https://baike.baidu.com/item/箱形图/10671164?fromtitle=箱线图&fromid=10101649&fr=aladdin
这里写图片描述
箱线图的优点就是可视化,很容易看出异常点以及数据大致分布,注意理解箱线图的时候不要把“内限”和上下边缘混淆,箱线图有几个元素:上边缘,上四分位数(Q3),中位数,下四分位数(Q1)和下边缘,四分位距(IQR)为(Q3-Q1),而内限为 [Q1-1.5IQR,Q3+1.5IQR],内限范围以外的都是异常点,而图中上下边缘是内限范围内的数据集中的最大最小值,不是内限范围,这里不要搞混。
5.三西格玛原则(也是比赛中最终采用的数据处理方法,提高好几分=。=)
即数据集中超过三倍标准差的数据,我们就认为是异常点也叫离群点,需要删除或者用三倍标准差代替,由于本赛题数据集数据0太多的,采用的是三倍标准差去代替。
预测方法
然后就是预测方法了,尝试过了许多的时间序列预测方法,稍微简单点的时间序列方法,移动平均法(MA),自回归法(AR),二次指数平滑法,(局部)线性回归,Arima(还挺复杂的)等等,还有一些高大上的的机器学习算法bp神经网络,长短期记忆神经网络(LSTM)等等,然而最后还是采取了大部分同学试过都说好的二次指数平滑法,高大上的方法即难敲代码(毕竟不能用第三方类库)并且效果还不好,。。。
贴上核心方法(指数平滑)的链接: http://wiki.mbalib.com/wiki/二次指数平滑法,认真看一下还是比较好理解的,原理大概就是每一个数据都会收到前面数据的影响(加权和),但是时间距离越远的数据会影响越小,比较适用于时间序列问题的预测。
实际上比赛过程中大家都觉得预测是一个玄学的问题,因为他的数据实在是太难训练出一个好的拟合曲线了,要不就过拟合,要不就欠拟合,导致许多高大上的算法都失效了,反倒是指数平滑,还有均值大发反而鲁棒性更加好。下面说一下放置的资源优化问题。

2.放置问题

实际上赛题的放置阶段是一个二维装箱问题(初赛),优化维度有两个CPU和MEM,一开始是按照大赛提示的方法用首次适应法(FF)进行装箱,后来看了一些资料,又换成排序首次适应法(FFD),效果略好于FF,不过发现分数一直提不上去,发现FFD在预测虚拟机种类少,预测周期短的时候,效果还好,但是数据量增加以后就不行了,后来又翻阅资料发现了许多智能优化算法处理装箱问题的论文和资料,最终选择了模拟退火+FF的组合,发现数据量大的时候,因为FFD是按照某种资源维度的大小排序以后再去装箱,而模拟退火的过程中,做得操作是每次温度下降都会随机变换需要装箱的虚拟机的位置顺序,在用FF去装箱,保证了最后解的多样性,但是实际上由于方法的随机性,导致最后分数波动上下3分左右,最后采取了一个骚操作,因为发现退火算法每运行几次都会有一次装箱的利用率很高,我就直接在整个模拟退火过程的外边加了一个循环,取最优的结果,实际上相当于取自己好几次提交代码的最好分数,改进以后稳定了很多。最后说一下比赛过程高分同学都用了的一个小技巧就是装箱过程结束后,加一个填补过程,就是把没装满的箱子再用几个小号的虚拟机填补进去,使得每个箱子尽可能满,然后把多加进去的虚拟机,对应在预测的虚拟机中加进去。
贴一个介绍装箱问题的链接:https://wenku.baidu.com/view/53d87ecbf12d2af90242e6e9.html,包括多种基础装箱算法的分析。

文章主要是分享一下,比赛过程中的用的部分方法,供大家讨论学习和交流,具体实现还是费了不少脑筋的,整个过程也是痛并快乐着,总体来说参赛体验还是不错的,提高了自己的代码能力以及自学能力,想起今年好声音上李健说的那个成语“有的放矢”,有目标的学习,实际上是带着一种渴求的心理去学习,效率会更高,效果会更好,结合实际问题去写代码也会更有一种真正解决问题的成就感!
哈哈,不多废话了,初赛代码已经开源在GitHub上了,需要的同学可以看一下!

github链接: https://github.com/neuNoviceZhao/2018-
喜欢的朋友帮忙star一下吧=。=!!!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值