2017华为CodeCraft回顾

2017.4.26

经过一个多月的努力,华为CodeCraft结束了。最后结果止步复赛,还是自己实力不够,大佬们还是强。不过对于我一个学电子的来说,第一次搞图论的算法感觉自己还是尽力了,开始群里大佬说的各种算法完全不知道,虽然现在还是有很多不懂,不过还是有一些收获的(起码知道了一些图的算法和启发式算法)。


还在路上,稍等...
复赛的成绩是在中游,top18刚好在中间。。。


初赛

大概是在3.10左右才开始决定参加比赛的,然后是找队友的问题,自己本身在外面实习不在学校,虽然可以线上组队不过感觉要组的话还是能线下交流的方便,问了下我一起实习的同学(搞硬件的)。。。唉,最后还是自己搞算了,考虑到自己还有别的活要干不能所有时间搞,所以还是别坑别人好(忍心拒绝了师弟的组队邀请),走上了单排的不归路。想起了不知道拿看的一句话“一个人走的快,两个人走的远”,现在想想还真是这回事,当然在线下复赛的时候还是看到一些单干的大佬。

开始先按:费用流->选服务器两步走。

(1)费用流
不幸的是最关键的费用流开始就错了,并不是最小费用。。。orz,好气啊,还是太菜。
开始整天纠结两个消费点的最小费用流冲突了怎么办,看了一些文章里面提到的负路径,路径能有“后悔”的机会,开始还是没有完全理解,直到后面简单画了一个图才突然明白过来,原来是这么简单的东西。

假设简单的图,2个服务器和2个消费点,在计算费用流的时候先找c1然后找c2就会发生下面的情况,明显c2的费用流绕了一大圈,满足流量但不是最小费用。。。开始纠结了很久,网上看到单向图最大流是加入反向弧,没好好理解。(还是太菜)
这里写图片描述

正确费用流应该是下面


还在路上,稍等...
图A:开始的残留网络r。
图B:分配c1消费点的10流量,增广路为1->4->s2,残留网络r(1,4) = 0, r(4,1) = 20, r(4,s2) = 0, r(s2,4) = 20。本来双向图就相当于自带反向弧,只不过单向图的初始反向弧=0,这里的初始反向弧=10,在分配N流量增广路时,增广路的残留r-N,反向弧r+N,就有图B的残留网络。
图C:分配c2消费点的10流量,增广路为2->4->1->3->S1,残留网络如图C蓝色变化,注意节点1-4,这时r(1,4) = 10, R(4,1) = 10,其实就相当于没使用1-4。
图D:图C对应的流量网络,就是最小费用,再通过DFS把流量路径输出。

另外,要把所有消费点连起来形成超级汇点t,所有的服务器连起来形成超级源点s,就相当于单源单汇问题(开始没有理解反向弧的用处,超级源汇点也不知道,真不知道我怎么这样也能进复赛,本来打算初赛后都改回来的,各种各样的事情就没时间改,一直用着不是最优的费用流orz,虽然实际离最优也差不远。写代码前还是要多查资料,特别时自己第一次搞的东西)。

(2)选服务器
题目重点还是在选服务器上。
首选考虑增删服务器的问题,删要比加服务器简单,删服务器直接把服务器上的流量退出来,然后在原基础上跑费用流,不用重新算在图大的时候能非常节省时间,至于加服务器的话比较麻烦没有想好,之后有空再研究下。

选服务器开始感觉能用退火和遗传,遗传的话交叉和变异过程中相当于加服务器和删服务器操作,重新计算费用流可能会比较费时间;退火的话可以开始加多点服务器,然后一个个删,删的时候不用重新计算,可以用上一步的结果,费用流计算快,问题是把最优的服务器删了就gg了。

那就直接用退火吧(其实是感觉遗传比较麻烦)。

待选节点服务器包括2个部分:
1.直连的节点
2.每个消费节点找最近的2个消费节点的最短路径,通过最短路径的节点计数,通过路径多的节点可能包括最优的服务器可能性大。
(上面2个在服务器费用低的时候比较好用)

选服务器步骤:
1.添加所有直连的服务器。
2.删除服务器直到不能删除,尝试删除每个服务器(只删有流量分配的,不然开始就把没流量分配的服务器都删掉了),删能减少最多费用的(其实就是贪心,后来加入随机性)。
3.加入待选节点第2部分的服务器(可以不加所有,随机选取加)。
4.重复2,直到时间结束。

上面的方法初赛服务器费用增加前是非常好用的,保持前5左右(大概也是因为大佬都在隐藏着),后来初赛服务器费用增加后,上面的方法就GG了,直接掉到20多名,还好能进复赛,当时真的惊险刺激。


复赛4.23

复赛主要区别:
1.服务器等级,不再是提供无限流量。
2.部署服务器需要费用。
3.规模变大,初赛最多800点,复赛时高级case 1200点。

初赛后有比较重的项目任务,结果直接1个多星期没动代码,大概最后一个星期才开始改,想着总不能0分吧。。。算法思路没怎么改,增加复赛的要求(还好代码算比较好改),优化了速度,最后排名也是在中游。

不得不吐槽下复赛,不知道时web问题还是服务器问题,反正就是炸了,等了1下午就成功提交了1次代码,最后复赛隔日进行。。。(感觉好亏,我过去干嘛,还是从广州到武汉,车票都好亏orz,只报销长沙到武汉的票价)


总结

参加完比赛还是有些收获的,感谢华为办的比赛,如果上一年早点知道codeCraft也一定会参加。比赛时经常看排行榜还是非常好玩,特别是正赛的时候非常刺激。

平时白天有工作任务,只能晚上去写代码,能坚持下来参赛感觉自己也是尽力了。从3月开始后就没有周末,晚上经常11点才回宿舍,能进入复赛还是挺满足的,当然还是有遗憾不能进入决赛,不过大佬就是大佬,实力上的差距没办法,能全力准备的话说不定能冲击下。

另外就是1+1>2,团队还是非常重要的,单干思路窄,容易走死方向,因为自己各种原因没组队也是一个遗憾吧。

之前有空再把垃圾代码整理下放github吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值