2021华为软挑赛题_思路分析——实时更新,做多少更多少(一)
- 赛题直达
https://download.csdn.net/download/weixin_44459972/15731297- 附上后文链接
2021华为软挑赛题_思路分析——实时更新,做多少更多少(二)
2021华为软挑赛题_思路分析——实时更新,做多少更多少(三)
2021华为软挑赛题_思路分析——实时更新,做多少更多少(四)
2021华为软挑赛题_思路分析——实时更新,做多少更多少(五)
2021华为软挑赛题_思路分析——实时更新,做多少更多少(六)
2021华为软挑赛题_思路分析——实时更新,做多少更多少(七)
2021华为软挑赛题_思路分析——实时更新,做多少更多少(八)
文章目录
本专栏食用建议
- 随着文章越更越多,本专栏的内容到底该如何食用,笔者在此做出如下建议,望能为参赛的诸位节省宝贵的时间和精力:
- 新朋友可以先阅读第八篇,附标准输入、输出、删除源码,可做baseline,直接提交(建议可在此基础上修改,如若封号,后果自负)。
- 第七篇文章:training-1跑出了4533492832的结果,training-2跑出了5316109914,此结果是在无迁移无删除的情况下得到的,附源码。
- 本专栏内容第一篇为思路的初步探索,适合没有多少思路或者对赛题把握比较模糊的朋友。当然,在赛程后期,有朋友已经做完提交想要在温故一遍赛题的话,亦可回顾此文。
- 至于第二篇文章,确实建议大家可以详细浏览,包含着鄙人对于此题的主要思路,至少相比于同类文章,个人认为此想法是最为可能落地的一种(暂不谈算法效率)。
- 接下来的三、四、五三篇文章(后面大致如此),主要是对第二篇文章的代码实现,可尽可能地去读最新的代码,毕竟,写着写着发现之前问题的事情也不是头一次发生,望诸位见谅~
- 至于第六篇文章,鄙人决定对诸位朋友所提的问题加以总结,在此篇做统一的解释。当然,这里的解释一定不能完全的解决大家的问题,但,鄙人自当尽力,诸位也各取所需~
- 当然,以上不过是鄙人的小小建议,若有朋友希望能够完全的去理解鄙人解题的全部心路历程,逐篇阅读亦未尝不可~
3月10日更新
一、赛题分析
1. 赛题输入解读:
1.输入N,(1≤N≤100)
2.输入N行(元组),可以采购的服务器类型数量
型号 | CPU 核数 | 内存大小 | 硬件成本 | 每日能耗成本 |
---|---|---|---|---|
host0Y6DP | 300 | 830 | 141730 | 176 |
hostHV3A3 | 290 | 580 | 111689 | 139 |
hostD4V30 | 418 | 412 | 121272 | 152 |
…… | …… | …… | …… | …… |
3.输入M,(1≤M≤1000)
4.输入M行(元组),售卖的虚拟机类型数量
型号 | CPU 核数 | 内存大小 | 是否双节点部署 |
---|---|---|---|
vm38TGB | 124 | 2 | 1 |
vmMRUNJ | 60 | 2 | 1 |
…… | …… | …… | …… |
5.输入T,(1≤T≤1000),T 天的用户请求序列
6.输入R,非负整数,当天共有 R 条请求
7.输入R行(元组),每日增/删的请求
add/del | 虚拟机型号 | 虚拟机 ID |
---|---|---|
add | vmPCXA5 | 264022204 |
del | NULL | 897872834 |
…… | …… | …… |
2. 赛题解决大致流程分析:
根据已有的输入数据,大致可分为三类:服务器数据、虚拟机数据、每日请求数据。
-
为数据定义相关类(除三类输入数据外,应该有一个类记录当拥有的总资源以及总花销)
-
根据服务器数据,可先分析一波服务器的性价比,决定今后购进服务器时,购进那种最合适。
-
服务器性价比具体计算方式:
- (硬件成本/CPU 核数)核心数/(内存数+核心数)+
(硬件成本/内存大小) 内存数/(内存数+核心数)
-
确定是预购服务器资源,根据当日请求调整后一天的购买服务器资源策略,还是第二天处理第一天的请求。因为实际情况应该是先有资源,再有请求。或者可以,两个都有
-
算法大致流程(肯定还有问题):
Ps:当前思路仅供参考,不周之处海涵。
3月11日更新
二、输入数据梳理:
1. 题中所给样例输入如下:
#总输入
2
(NV603, 92, 324, 53800, 500)
(NV604, 128, 512, 87800, 800)
2
(c3.large.4, 2, 8, 0)
(c3.8xlarge.2, 32, 64, 1)
3
2
(add, c3.large.4, 5)
(add, c3.large.4, 0)
2
(del, 0)
(add, c3.8xlarge.2, 1)
3
(add, c3.large.4, 2)
(del, 1)
(del, 2)
2. 样例解读:
2#种
(NV603, 92, 324, 53800, 500)
(NV604, 128, 512, 87800, 800)
服务器总表 = (型号, CPU 核数, 内存 大小, 硬件成本, 每日能耗成本)
2#种
(c3.large.4, 2, 8, 0)
(c3.8xlarge.2, 32, 64, 1)
虚拟机总表 = (型号, CPU 核数, 内存 大小, 是否双节点部署)
3#天
2#条
(add, c3.large.4, 5)
(add, c3.large.4, 0)
2#条
(del, 0)
(add, c3.8xlarge.2, 1)
3#条
(add, c3.large.4, 2)
(del, 1)
(del, 2)
3. 解决方案:
1.依据每一天的虚拟机请求数据,将add请求加入addList中,将del请求加入delList中。
- addList(虚拟机型号, 虚拟机 ID)
- delList(虚拟机 ID)
2.addlist、dellist中的数据会被前一天的数据覆盖(建议读一天处理一天的数据,否则需要接受800天的数据,每天还需单独存放,会比较麻烦),因此建立一个requireList记录全部已经添加过得虚拟机(方便执行删除操作)。
- requireList(虚拟机 ID)
3.接下来对当天的请求数据进行处理:
If delList == NuLL:
调用Shopping()方法
else:
调用Del()方法
其中Shopping()方法应该包含:
-
匹配:addList中的虚拟机型号与虚拟机总表匹配,得到addList中每一项的 CPU核数, 内存大小, 是否双节点部署,得到dayVmRequireList;
-
加和:将dayVmRequireList中每一项的 CPU核数, 内存大小进行加和,分别得到coreNum、memoryNum。
-
购买:依据之前性价比功能选出的性价比最优的服务器的CPU核数(core), 内存大小(memory),取shoppingNum为服务器购买的数量。服务器购买数量公式如下:
shoppingNum = ⌈Max(coreNum / core, memoryNum / memory)⌉
-
分配:将dayVmRequireList中的数据按照单双节点排序,双节点在上,即先分配双节点(保证尽可能少的产生空隙,但这种方法每台服务器都有可能存不满)。若最终分配完成后发现服务器不够,则再买一台服务器,完成分配。
-
调度:(暂不考虑)
Ps:目前只考虑完整运行,购买、分配、调度有待扩展
3月12日更新
三、换一种解题思路
将购买、分配等问题统筹考虑,不在单线分开去做。
Ps:前提不考虑删除请求的,因为删除请求会涉及调度问题。
1. 引入:
刷Leetcode时遇到一道题:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
原题链接直达:https://leetcode-cn.com/problems/combination-sum/
通俗的讲,其大致意思就是让人凑数:从一个数组 candidates中找两个数加和等于目标数 target。本题借鉴这种解法,完成虚拟机的购买、分配和调度等问题。
2. 解决方案概述:
2.1 解题相关前提定义:
- 服务器总表 = (host型号, hostCPU核数, host内存大小, 硬件成本, 每日能耗成本,性价比)
- 虚拟机总表 = (vm型号, vmCPU核数, vm内存大小, 是否双节点部署)
- 每日请求总表 = (vm型号, 虚拟机 ID, vmCPU核数, vm内存大小, 是否双节点部署)
Ps:接下来将以training-data\training-1.txt中的第一天的请求数据为例加以说明。
- 服务器总表:80条数据,每一条代表一款可以购买的服务器;
- 虚拟机总表:800条数据,每一条代表一款可供用户购买的虚拟机;
- 每日请求总表:142条数据,数据与“虚拟机总表”匹配得来,每一条数据代表一个用户购买了一台虚拟机的请求。
2.2 解题流程:
- 首先,将服务器总表按照性价比进行升序排序(因为之前性价比计算公式算出的性价比越小,购买该服务器的性价比越高)。
- 其次,遍历每日请求总表,用其中的vmCPU核数 、vm内存大小依此去凑服务器总表中每款服务器的hostCPU核数、host内存大小(这里对于每日请求总表中每一项的访问可以随机组合),并记录凑出每一款服务器的虚拟机的组合情况,以及在该情况下,所凑之数与此款服务器hostCPU核数、host内存大小之间的差值。
- 接下来便有两种方法选取需要购买的服务器:
- 汇总所有80款服务器的凑数结果,寻找结果中差值最小的服务器,若出现相同的情况,选前者购买(因为数据已经提前按照性价比排序)。
- 综合性价比与凑数结果的差值,寻找适中者购买(此处有待扩充)。
- 卖完此服务器台后,从每日请求总表中删除该种情况下对应的虚拟机请求组合。
- 得到的新的每日请求总表循环执行凑数过程,直至请求总表为空截止。
Ps:此算法完成了虚拟机分配与服务器购买,在不考虑删除请求的前提下,实现了每次购买到的服务器都可以尽可能多的被利用,减少了产生空隙的机会,提高了服务器资源的利用率;同时,按照性价比优先进行购买,可以尽可的多的减少花销(性价比,暂时没有考虑服务器的每日能耗成本)。