昨天比赛已经结束,之前我说过会在赛后分享我的算法的,所以现在就来分享一下。不管好坏,大家若有兴趣,且看便是。
因为我是学数学的,思考问题便从数学的角度考虑。
这是可以看作一道整数线性规划问题:
假设需求峰值 mC,nG(这里统计需求峰值时取A B节点较大的那一个)。
约束条件:
92x+128y>=2m
324x+512y>=2n
目标函数:
min(53800x+87800y)
用单纯形法求得购买数量的最优解{},然后对上对上取整。
单纯形法是求解线性规划的主要方法,但是解有可能是小数。整数线性规划主要方法有割平面法和分枝定界法,但都是在单纯形法基础上做了改进。但当前需求较复杂,即便求得了整数解,因为有些服务器边角料用不上,以及还没考虑每日能耗的问题,实际情况只会更复杂。我这里只用单纯形法求得解后对上取整,求得相对最优解。如果想得到绝对最优解,要穷举所有情况,我认为这是不现实的。
求得各服务器应购买数目后,因为求得的可能是小数,故对上取整(因为各服务器会有些边角料用不上,故实际需求只会更多)。
购买阶段,因为只有两个约束条件,故用单纯形法来再多量也只有两个量有值。我计算了它们的性价比,一般是一个CPU性价比高一个是内存性价比高。一般来说,两种东西,各有优缺点才能共存,如果一方各方面都比另一方强,在没有总量限制条件下,弱的一方完全没有生存空间。这也许可以给用贪心的一些启示。
之前已求得每日峰值,而可使用服务器为已购服务器,故这仍是一个整数线性规划的问题,再一次使用单纯形法求得每日开机数的最优解。
求解每一天的需求仍可以看作是整数线性规划问题:
假设第day日需求峰值 C,G。
约束条件:
92x+128y>=2
324x+512y>=2
x<=
y<=
目标函数:
min(500x+800y)
这里只有两种服务器,故只有x、y两个变量。如果像训练集里那样,有100个服务器,变量就是。
想法很美好,离现实却还差很远。代码运行以后发现,需求的服务器大大超过了计划分配的量。这里面可能有服务器边角料用不上的原因,还有可能就是代码里有些bug导致服务器误分配很多。还有问题就是如果虚拟机分配从前往后遍历已开机服务器,就会导致算法时间超支,如果随机分配又不能保证物尽其用。这样就和设想的情况偏离了很远了,以至于采用整数线性规划优化的效果大打折扣,还不如那些用贪心的。
我后来跟那些前排大佬聊天,前排基本上都是用贪心的,加一些trick。省时省力,工程量也不大。我因为工程采用了单纯形法,以致我工程量太大,差不多是一个小型软件的量了。相比于那些仅用贪心就能进入排行榜前列的人来说,我的做法显得有点吃力不讨好。
由于工程量很大,以至于寻找bug很困难,幸好有大佬的判题器,可以帮我定位bug。
不过做到最后我放弃了,还有bug没有解决。即便排查了bug,能够提交了费用还是太大(为了不超时我改成了虚拟机随机选几个服务器分配,这样就离预想差很远了),进不了前64。
做到后面看看排行榜就大概知道他们用什么策略。我想复杂了,但不能说这样做不对,只能说缺乏比赛经验,如果经验丰富就知道什么样的比赛该用什么样的策略。
分享出来,权当是个教训。本来说赛后还要分享代码的,我就不拿出来了吧,还有bug,算法告诉你,你也能复现不是。