2021华为软件精英挑战赛

2021华为软件精英挑战赛

github地址: https://github.com/lh4027/huawei-software-competition2021.git.

比赛心得

今年首次参加华为软挑,一开始只想进前64 强拿个证书就满足了,没想到队友太猛直接肝进初赛正式赛第六。
复赛由于时间关系没有好好准备加上没有很好的思路,训练赛的时候掉到了16,现场赛3个小时又出现了意外(换了数据集后,训练赛提交成功的代码竟然正式赛运行异常),只好现场改用初赛最好成绩那份代码,不出意料,最后只取得了复赛21的成绩,总的来说还是比较遗憾的,毕竟复赛期间改良的代码没有用上。初赛,复赛成绩如下:

在这里插入图片描述
接下来我会具体总结一下我们队伍的思路和方法,时间仓促,可能有叙述不合理的地方,见谅。

赛题分析:(具体赛题也上传在github上)

题目中所给的虚拟机有两种部署方式,分别为单双节点部署,单节点部署指的是一台虚拟机所需的资源(CPU和内存)完全由主机上的一个节点提供;双节点部署指的是一台虚拟机所需的资源(CPU 和内存)必须由一台服务器的两个节点同时提供,并且每个节点提供总需求资源的一半。
    赛题要求根据所给的请求序列,创建服务器,部署虚拟机,或者按照用户请求在对应的服务器上删除相应的虚拟机。但要注意,服务器上的任意一个节点(A和 B)上的资源负载(CPU 和内存)均不能超过其容量上限。在完成每一天的服务器的扩容之后,在处理每一天的新请求之前,你还可以对当前存量虚拟机进行一次迁移,即把虚拟机从一台服务器迁移至另一台服务器。对于单节点部署的虚拟机,将其从一台服务器的 A 节点迁移至 B 节点(或反之)也是允许的。但迁移的虚拟机总量不超过当前存量虚拟机数量的千分之五。
    我们可以发现这是一个类似于装箱的问题,把服务器比作箱子,把虚拟机比作需要放进去的货物。官方推文上给的提示复杂难懂,但本质好像也是多维装箱问题。

我们程序的流程

首先解析出来所有服务器类型,虚拟机类型,以及请求天数,然后对每一天到来的虚拟机请求处理,迁移,部署最后扩容。
我们的方法是针对每一天的请求数据来进行的,(初赛一次性给出了所有天数的请求,意味着可以用上帝视角去处理这个问题,但是实际场景中不可能知道全部数据,只能预测到有限天数的请求,这也是复赛赛题变动的地方)。
第一天的时候我们根据所有的Add请求进行扩容,也就是首次购买服务器,如何选取服务器会在后续扩容策略里面详述,然后再进行虚拟机的部署,也就是分配,我们的add请求和delete请求是分开处理的,先处理完所有add请求,再去处理所有delete请求,因为我们是基于一天数据的全局视角来处理数据的,这对我们的程序来说很重要
后面的每一天我们先取出所有虚拟机请求,首先进行迁移,这里的迁移其实是针对上一天的,因为上一天会有删除请求,会空出很多服务器资源,这时候就需要对这些空置资源重新整合。然后进行虚拟机的分配,也就是部署add请求的虚拟机。将这一天的所有add请求单独拿出来,往剩余的服务器资源里面部署,直到剩余服务器资源再也部署不进去虚拟机后终止。
将剩余的add请求交给扩容,选择购买一批服务器放入这剩下的add请求,至此所有add请求我们都处理完毕,接下来处理所有delete请求。一天结束。循环往复,直至最后一天。

扩容策略:

我们的扩容策略其实就是基本的装箱问题加贪心算法,主要利用了降序梯度最佳适应算法,加上一些小技巧,在我们的代码中,将每天分配部署后的剩余虚拟机add请求拿过来,按照这些请求所需资源大小降序排列,即让大的虚拟机先放,遍历所有可购买的服务器,每一台服务器放入其自身容量极限的虚拟机后,计算服务器剩余资源,取出差值最小的服务器,一次循环选出一台服务器,每次选出后服务器后,记录该服务器上的虚拟机,这里在购买服务器的同时已经相当于把这些虚拟机分配好了后面直接查找这些虚拟机所在的服务器就可以直接输出了

每选择好一台服务器后,就更新现在的虚拟机请求总表,即去掉已经分配在购买的服务器上的虚拟机请求。当这一天的虚拟机总表为空时,我们就完成了扩容。这种方法使得利用率很高,但有个很大问题,时间复杂度会很高,尤其是一天的虚拟机请求特别多时,会很耗费时间。
这里我们用了一些小技巧,一个是数据切分,另一个是按照虚拟机内核比>1和内核比<1分类,服务器也按照内核比分成两类。流程:数据切分->按照内核比分类->按照请求所需资源大小降序排列,这样当虚拟机请求数很多时(程序中设置为3000),我们分为几个数据块,每个数据块单独执行扩容策略,再用上多线程,很好地解决了超时问题。

分配策略:

每天在扩容之前,我们需要将虚拟机请求先进行一次部署,如何保证较好的资源利用率尤为重要,在这个阶段,我们部署越多的虚拟机请求,扩容时需要购买的服务器就越少,成本就会越低。这里使用的策略依旧是贪心算法,找放入虚拟机后剩余服务器资源量最小的,每次遍历所有服务器,策略和扩容类似。

迁移策略:

将剩余服务器资源从大到小排序,将剩余资源多的服务器上的虚拟机迁移到剩余资源少的服务器上,复杂度很高,采用了很多剪枝方法,加了很多限制,如迁移成功率,失败率等。(膜拜大佬队友,优化时间很有一套)具体可看代码。

复赛的时候我们又改进了分配算法和迁移算法,用初赛数据集测试总成本可以达到11亿以下,可惜复赛现场赛出了bug,所以代码一定要多测试,提升鲁棒性。
以上仅为我们团队思路和方法,非科班出身,能力不足请轻喷。
最后总结一下,在参加这类比赛时,代码更新迭代非常快,最好做好版本管理和代码留存说明,写代码时多思考,不要堆砌代码,否则后期自己都看不懂自己的代码了,修改起来很麻烦。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值