2021华为软挑赛题_思路分析——实时更新,做多少更多少(四)
前言
- 最近代码越更越长,都放到一篇怕朋友们引起不适,故如此布局文章,谅解~
- 本文为在上篇文章的基础上,将“2021华为软挑赛题_思路分析——实时更新,做多少更多少(二)”中购买分配算法的偏数据处理部分(具体哪部分文中介绍)。
- 代码越更越长,鄙人尽力加全注释,但知道仍难解决朋友的全部疑惑,这里只能劝朋友多调试,毕竟不手写还是很难完全理解。
- 不过,大家目的不同,若果只是借鉴,请自行取用~
3月16日更新
1.今日更新——购买分配算法前期数据处理
下方的代码,在昨日的基础上增添了shoppingAndDistribution()购买分配算法,解决了购买分配算法在前期的数据处理问题,数据处理的思路做个归纳:
- 将hostListAll服务器列表按照hostXingJiaBi性价比排序。
- hostListAll服务器列表按照核内比分类(单写了一个方法classifyByCoreMemBi()自认为是命名鬼才,哈哈),分成hostCoreMemBiBigList(大于1), hostCoreMemBiSmallList(小于1)。
- 匹配dayListAll每日请求中虚拟机型号与vmListAll虚拟机总表中的虚拟机型号,将从vmListAll中匹配到的vmCpuNum,vmMemSize,vmDoubleOrNot,vmCoreMemBi增添addRequireList中的数据。
- 将dayListAll每一个元素的addRequireList按单双节点分类。
- 调用DayRequire类内置averageCoreMemBi()方法计算平均核内比。
- 调用sortByAverageCoreMemBi()方法,判断单、双节点请求列表的平均核内比是否大于1,若大于1,将两个列表按照vmCpuNum(核数)将vm升序排列; 否则,按照vmMemSize(内存容量)升序排列。
- 到此截止,望朋友可以享受思考的过程,加油~
# 代码解决2021华为软件挑战赛中的数据输入、购买分配算法前期数据处理问题
# 所有注释为了便于说明,以training-1.txt中的数据为例
# 代码中注释掉的print,多数可自行解封看看预期结果
# !!!*****!!! 为昨日代码的出错点
# 技艺不精,私事繁忙,照顾不周,多担待!
# 导入numpy库
import numpy
# 服务器类
class Host:
hostType = '' #服务器类型
hostCpuNum = 1 #服务器CPU数
hostMemSize = 1 #服务器内存容量
hostHardWareCost = 1 #服务器硬件开销
hostDayCost = 1 #服务器每日开销
hostXingJiaBi = 1 #服务器性价比:(硬件开销*(核数/核数+内存容量)/核数) + (硬件开销*(内存容量/核数+内存容量)/内存容量)
hostCoreMemBi = 1 #服务器核内比:核数/内存容量
# 计算性价比
# !!!认真观察的道友应该能发现,此处公式与昨日略有不同,但与昨日数值结果相同,可自己细品,理解鄙人定义的性价比的意义!!!
def xingJiaBi(self):
self.hostXingJiaBi = ((self.hostHardWareCost * (self.hostCpuNum / (self.hostCpuNum + self.hostMemSize)))/ self.hostCpuNum) + ((self.hostHardWareCost * self.hostMemSize / (self.hostCpuNum + self.hostMemSize)) / self.hostMemSize)
# 计算核内比
def coreMemBi(self):
self.hostCoreMemBi = self.hostCpuNum / self.hostMemSize
# 虚拟机类
class Vm:
vmType = ''
vmCpuNum = 1
vmMemSize = 1
vmDoubleOrNot = 1
vmCoreMemBi = 1
# 计算核内比
def coreMemBi(self):
self.vmCoreMemBi = self.vmCpuNum / self.vmMemSize
# 每日请求列表类——输入数据时使用
class DayRequire:
requireNum = 0
requireType = ''
vmType = ''
vmId = ''
averageDoubleCoreMemBi = ''
averageSingleCoreMemBi = ''
# !!!昨日出错重点,以前一直没发现,pyhton类中定义的列表是全局变量!!!
# 解决方法:通过初始化方法,将列表定义为self的局部变量
def __init__(self):
self.addRequireList = []
self.addRequireList_Double = [] # 列表中依此为requireType, vmType, vmId,
# vmCpuNum, vmMemSize, vmDoubleOrNot, vmCoreMemBi
self.addRequireList_Single = []
self.delRequireList = []
# !!!增加了两个为列表赋值的函数,只为美化代码!!!
def addRequireListAppend(self):
self.addRequireList.append([self.requireType, self.vmType, self.vmId])
def delRequireListAppend(self):
self.delRequireList.append([self.requireType, self.vmId])
# 计算每日add请求平均核内比
def averageCoreMemBi(self):
tempList = [require[6] for require in self.addRequireList_Double]
self.averageDoubleCoreMemBi = numpy.mean(tempList)
tempList = [require[6] for require in self.addRequireList_Single]
self.averageSingleCoreMemBi = numpy.mean(tempList)
# 一次性读入全部文件
def readTxt(filename):
try:
f = open(filename, "r")
line = f.read()
return line
finally:
f.close()
#按核内比分类
def classifyByCoreMemBi(numpyList):
# 核内比大于一的分一类,小于一的分一类
posCoreMemBiBig = numpy.argwhere(numpyList > 1)
# print(posCoreMemBiBig)
CoreMemBiBigList = [numpyList[n[0]] for n in posCoreMemBiBig]
posCoreMemBiSmall = numpy.argwhere(numpyList <= 1)
CoreMemBiSmallList = [numpyList[n[0]] for n in posCoreMemBiSmall]
return CoreMemBiBigList, CoreMemBiSmallList
def sortByAverageCoreMemBi(dayList):
# 处理Double
if dayList.averageDoubleCoreMemBi >= 1:
# 取出vmCpuNum存成列表
vmCpuNumTempList = [addRequireList_Double[3] for addRequireList_Double in dayList.addRequireList_Double]
vmCpuNumTempList = numpy.array(vmCpuNumTempList)
# 按照vmCpuNum升序排序
posVmCpuNumList = numpy.argsort(vmCpuNumTempList)
dayList.addRequireList_Double = [dayList.addRequireList_Double[n] for n in posVmCpuNumList]
print(dayList.addRequireList_Double)
else:
# 取出vmMemSize存成列表
vmMemSizeTempList = [addRequireList_Double[4] for addRequireList_Double in dayList.addRequireList_Double]
vmMemSizeTempList = numpy.array(vmMemSizeTempList)
# 按照vmMemSize升序排序
posVmMemSizeList = numpy.argsort(vmMemSizeTempList)
dayList.addRequireList_Double = [dayList.addRequireList_Double[n] for n in posVmMemSizeList]
# 处理Single
if dayList.averageSingleCoreMemBi >= 1:
# 取出vmCpuNum存成列表
vmCpuNumTempList = [addRequireList_Single[3] for addRequireList_Single in dayList.addRequireList_Single]
vmCpuNumTempList = numpy.array(vmCpuNumTempList)
# 按照vmCpuNum升序排序
posVmCpuNumList = numpy.argsort(vmCpuNumTempList)
dayList.addRequireList_Single = [dayList.addRequireList_Single[n] for n in posVmCpuNumList]
else:
# 取出vmMemSize存成列表
vmMemSizeTempList = [addRequireList_Single[4] for addRequireList_Single in dayList.addRequireList_Single]
vmMemSizeTempList = numpy.array(vmMemSizeTempList)
# 按照vmMemSize升序排序
posVmMemSizeList = numpy.argsort(vmMemSizeTempList)
dayList.addRequireList_Single = [dayList.addRequireList_Single[n] for n in posVmMemSizeList]
# 购买、分配算法——数据处理部分
def shoppingAndDistribution(hostListAll, vmListAll, dayListAll):
# 将服务器列表按照性价比排序
# 取出hostXingJiaBi单做一个列表
hostXingJiaBiList = [host.hostXingJiaBi for host in hostListAll]
# print(hostXingJiaBiList)
# 调用numpy.argsort函数排序返回下标
hostXingJiaBiList = numpy.array(hostXingJiaBiList)
# print(hostXingJiaBiList)
posHostXingJiaBiList = numpy.argsort(hostXingJiaBiList)
# print(pos)
hostListAll = [hostListAll[n] for n in posHostXingJiaBiList]
# 服务器按照核内比分类
hostCoreMemBiList = [host.hostCoreMemBi for host in hostListAll]
hostCoreMemBiList = numpy.array(hostCoreMemBiList)
[hostCoreMemBiBigList, hostCoreMemBiSmallList] = classifyByCoreMemBi(hostCoreMemBiList)
# 匹配每日请求中虚拟机型号与虚拟机总表中的虚拟机型号
# 增添addRequireList的数据
vmTypeListAll = [vm.vmType for vm in vmListAll]
vmTypeListAll = numpy.array(vmTypeListAll)
# 获取全部add请求的列表
addRequireListAll = [day.addRequireList for day in dayListAll]
# print(addRequireListAll)
# 为dayListAll中的addRequireList增添vmCpuNum,vmMemSize,vmDoubleOrNot,vmCoreMemBi
for i in range(len(dayListAll)):
# 取出一日的请求
vmTypeOneDayList = [oneRequire[1] for oneRequire in addRequireListAll[i]]
# print(vmTypeOneDayList)
posVmTypeListAll = [numpy.argwhere(vmTypeListAll == vmTypeOne) for vmTypeOne in vmTypeOneDayList]
# print(posVmTypeListAll[0][0][0])
# 为每一天的一项add请求增添vmCpuNum,vmMemSize,vmDoubleOrNot,vmCoreMemBi元素
for j in range(len(posVmTypeListAll)):
# print(posVmTypeListAll[j][0][0])
temp = [vmListAll[posVmTypeListAll[j][0][0]].vmCpuNum,
vmListAll[posVmTypeListAll[j][0][0]].vmMemSize,
vmListAll[posVmTypeListAll[j][0][0]].vmDoubleOrNot,
vmListAll[posVmTypeListAll[j][0][0]].vmCoreMemBi]
# print(temp)
# print(dayListAll[i].addRequireList[0])
dayListAll[i].addRequireList[j].extend(temp)
# print(dayListAll[0].addRequireList[j])
# 将addRequireList按单双节点分类
if dayListAll[i].addRequireList[j][5] == 1:
dayListAll[i].addRequireList_Double.append(dayListAll[i].addRequireList[j])
else:
dayListAll[i].addRequireList_Single.append(dayListAll[i].addRequireList[j])
# 调用类内置方法计算平均核内比
dayListAll[i].averageCoreMemBi()
# 判断单、双节点请求的平均核内比是否大于1
# 若大于1,将两个列表按照vmCpuNum(核数)将vm升序排列
# 否则,按照vmMemSize(内存容量)升序排列
sortByAverageCoreMemBi(dayListAll[i])
# 到这里,对数据的处理大致已经结束
# 文中注释掉的print,多数可自行解封看看预期结果
# 注释部分,鄙人已经尽力,但知道仍难解决朋友的全部疑惑
# 毕竟随着代码越更越长,不是手写的话很难完全理解
# 但,如果能看到这里的话,说明你很认真,接下来该准备执行凑数相关的功能了
# 明日依情况而定,一直还在商议是否要更出核心算法
# 望朋友多多支持!
# 将输入的数据处理,输出为hostListAll, vmListAll, dayListAll列表
# hostListAll, vmListAll 分别代表服务器总表与虚拟机总表
# dayListAll中存储800天的数据,每一个列表元素为一个类(oneDay)
def inputData(allData):
flag = 0
for i in range(len(allData)):
if allData[i].isdigit():
flag += 1
# flag=1 准备处理出服务器总表
if flag == 1:
hostTypeNum = int(allData[i])
hostListAll = [allData[i + j + 1] for j in range(hostTypeNum)]
# flag=2 准备处理出虚拟机总表
elif flag == 2:
vmTypeNum = int(allData[i])
vmListAll = [allData[i + j + 1] for j in range(vmTypeNum)]
# flag=3 接收所有天的全部请求 本页代码中的小弯弯
elif flag == 3:
dayNum = int(allData[i])
flag1 = 0
dayListAll = [0 for j in range(dayNum)] #存DayRequire类
# 遍历800日后的全部输入 可体会一下同级下的break
for j in range(i + 1, len(allData)):
if allData[j].isdigit():
flag1 += 1
# 读不懂可解开下句封印 尝试观察输出
# print(allData[j], allData[j+1])
#过滤请求类数据,接收每日请求的数值 譬如第一日142
if flag1 <= dayNum:
#新建一个类 用于接收每一天的请求数据
oneDay = DayRequire()
oneDay.requireNum = int(allData[j])
# 读不懂可解开下句封印 尝试观察输出
# print(oneDay.requireNum)
# 下方for循环接收每一天的请求数据 存到oneDay的类中 传给dayListAll
for k in range(j + 1, j + oneDay.requireNum + 1):
# 按逗号切分每条请求
tmpeList = allData[k].split(',')
# 切分后的数组若只有两项表明为del请求 传给oneDay.delRequireList
if len(tmpeList) == 2:
# 清除多余空格、括号
oneDay.requireType = tmpeList[0].replace('(', '')
oneDay.vmId = tmpeList[1].replace(')', '').replace(' ', '')
oneDay.delRequireListAppend()
# 切分后的数组若有三项表明为add请求 传给oneDay.addRequireList
elif len(tmpeList) == 3:
# 清除多余空格、括号
oneDay.requireType = tmpeList[0].replace('(', '')
oneDay.vmType = tmpeList[1].replace(' ', '')
oneDay.vmId = tmpeList[2].replace(')', '').replace(' ', '')
oneDay.addRequireListAppend()
dayListAll[flag1 - 1] = oneDay
# 执行完flag==3中的内容后,可直接跳出最外层for循环
break
# 为Host类赋值,使hostListAll中每一个元素为一个Host类
i = 0
for host in hostListAll:
#分割数据去除空格、括号
host = host.split(',')
host[0] = host[0].replace('(', '').replace(' ', '')
host[4] = host[4].replace(')', '').replace(' ', '')
#赋值数据
tmpeHost = Host()
tmpeHost.hostType = host[0]
tmpeHost.hostCpuNum = int(host[1])
tmpeHost.hostMemSize = int(host[2])
tmpeHost.hostHardWareCost = int(host[3])
tmpeHost.hostDayCost = int(host[4])
tmpeHost.xingJiaBi()
tmpeHost.coreMemBi()
hostListAll[i] = tmpeHost
i += 1
# 为Vm类赋值,使vmListAll中每一个元素为一个Vm类
i = 0
for vm in vmListAll:
#分割数据去除空格、括号
vm = vm.split(',')
vm[0] = vm[0].replace('(', '').replace(' ', '')
vm[3] = vm[3].replace(')', '').replace(' ', '')
# 赋值数据
tmpeVm = Vm()
tmpeVm.vmType = vm[0]
tmpeVm.vmCpuNum = int(vm[1])
tmpeVm.vmMemSize = int(vm[2])
tmpeVm.vmDoubleOrNot = int(vm[3])
tmpeVm.coreMemBi()
vmListAll[i] = tmpeVm
i += 1
i = 0
return hostListAll, vmListAll, dayListAll
def main():
# to read standard input
# process
# to write standard output
# sys.stdout.flush()
#以training-1.txt为示例
filename = "training-1.txt"
#按换行分割全部数据
allData = readTxt(filename).split('\n')
# 根据下一条注释可以返回分割后的数据
# print(allData[0])
[hostListAll, vmListAll, dayListAll] = inputData(allData)
# 购买分配算法——仅有数据处理
shoppingAndDistribution(hostListAll, vmListAll, dayListAll)
# 根据下一条的输出,可显示第一天第一条请求
# print(dayListAll[0].addRequireList[0])
if __name__ == "__main__":
main()
总结
Ps:
- 不知过零点更新,还算不算16日。
- 哈哈还是参考工作时长吧!
- 如果大家有什么好的思路,或者本文代码的不妥之处,欢迎在评论区吐槽留言~
转载:https://blog.csdn.net/weixin_44459972/article/details/114905133
查看评论