其他工作:
2021华为软挑部分答疑——哪些你有错却总是找不到的地方,我来带你找啦(含标准输入代码)
这几天华为软挑好多人也是做的热火朝天,作为一个渣渣小孙也来探探,不探不知道一探吓一跳,天呐,自己菜的可怕。试了多次都还停留在超时上,😫😫😫!不过也算有一点小收获,
今年华为软挑的题是一个云上资源规划与调度问题,问题的主要是购买服务器和虚拟机部署在哪个服务器上以及虚拟机的迁移问题。大致就是这样:
这篇文章第一次写难免存在写问题,于是,小孙又再探了:
我的大致思路是来自这几篇论文:
今天写了个能解出结果的代码,代码如下:
import sys
import os
import re
import random
import numpy as np
import copy
import time
class GA:
def __init__(self):
self.P_c=0.8 #交叉概率
self.P_m=0.8 #变异概率
self.Pop_Size=10 #种群大小
self.Iter=10 #迭代次数
self.P_z=0.6 #选择概率
self.P_w=0.2
def Sever_Select(self,K,Sever):
V=copy.copy(K)
Selected_Sever = []
Select = random.choice(Sever)
Select_i = Sever_Machine(Select)
while V != []:
Select_V =random.choice(V)
result = Select_i.Judge_whether_to_insert(Select_V)
if result == True: # 随机配置
V.remove(Select_V)
if V==[]:
Selected_Sever.append(Select_i)
break
if result == False:
for i in range(len(V)):
result = Select_i.Judge_whether_to_insert(V[i])
if result == True:
V.remove(V[i])
break
if result == False and i >= len(V) - 1:
Selected_Sever.append(Select_i)
Select = random.choice(Sever)
Select_i = Sever_Machine(Select)
return Selected_Sever
def Encode(self,V,Sever):
Sev_Mac=[]
for i in range(self.Pop_Size):
Sev_Mac.append(self.Sever_Select(V,Sever))
return Sev_Mac
def Fitness(self,Sev_Mac,use_Day):
Fit=[]
for i in range(len(Sev_Mac)):
Fit_i=0
if Sev_Mac[i]==None:
print(i)
pass
else:
for j in range(len(Sev_Mac[i])):
Fit_i+=Sev_Mac[i][j].Hardware_cost+use_Day*Sev_Mac[i][j].Energy_cost
Fit.append(Fit_i)
return Fit
def Crossover(self,CHS1,CHS2):
ML=min(len(CHS1),len(CHS2))
R=random.randint(1,ML-1)
T0=[i for i in range(ML)]
random.shuffle(T0)
T0=T0[0:R]
for j in T0:
Load_1=CHS1[j].Node_Situation()
Load_2=CHS2[j].Node_Situation()
Sev = [CHS2[j].Model,CHS2[j].CPU_cores,CHS2[j].Memory_Size,CHS2[j].Hardware_cost,CHS2[j].Energy_cost ]
if Load_1[0]<=CHS2[j].CPU_cores/2 and Load_1[1]<=CHS2[j].CPU_cores/2 and\
Load_1[3]<=CHS2[j].Memory_Size/2 and Load_1[3]<=CHS2[j].Memory_Size/2 :
if CHS1[j].Energy_cost>=CHS2[j].Energy_cost and CHS1[j].Hardware_cost>=CHS2[j].Hardware_cost:
CHS1[j].replace_machine(Sev)
else:
if random.random()<self.P_z:
CHS1[j].replace_machine(Sev)
return CHS1
def Mutation(self,CHS1,Sever):
L=len(CHS1)
R=random.randint(1,L-1)
T0=[i_1 for i_1 in range(R)]
random.shuffle(T0)
T0=T0[0:R]
for i in T0:
Load=CHS1[i].Use_situation()
Load_CPU=Load[0]
Load_M=Load[1]
for j in range(len(Sever)):
if Sever[j][1]>=Load_CPU and Sever[j][2]>=Load_M :
if CHS1[i].Hardware_cost<=Sever[j][3] and CHS1[i].Energy_cost<=Sever[j][4]:
CHS1[i].replace_machine(Sever[j])
else:
if random.random()>self.P_w:
CHS1[i].replace_machine(Sever[j])
break
return CHS1
def Select(self,Fit_value,POP_SIZE):
Fit=[]
for i in range(len(Fit_value)):
fit=1/Fit_value[i]
Fit.append(fit)
Fit=np.array(Fit)
idx = np.random.choice(np.arange(len(Fit_value)), size=len(Fit_value), replace=True,
p=(Fit) / (Fit.sum()))
return idx
def main(self,V,Sever,use_Day):
CHS=self.Encode(V,Sever)
Best=[]
Best_Fit_end=None
for i in range(self.Iter):
Fit=self.Fitness(CHS,use_Day)
Best_Fit=min(Fit)
Best_Sev=CHS[Fit.index(Best_Fit)]
if Best_Fit_end==None or Best_Fit<Best_Fit_end:
Best.append(Best_Sev)
Best_Fit_end=Best_Fit
Select=self.Select(Fit,self.Pop_Size)
CHS=[CHS[C_i] for C_i in Select]
for j in range(len(CHS)):
if random.random()<self.P_c:
CHS2=random.choice(CHS)
C=self.Crossover(CHS[j],CHS2)
CHS[j]=C
for j_1 in range(len(CHS)):
if random.random()<self.P_m:
M=self.Mutation(CHS[j_1],Sever)
CHS[j_1]=M
return Best[-1]
class Virtual_Machine:
def __init__(self,V,user):
self.Model=V[0]
self.CPU_cores=V[1]
self.Memory_Size=V[2]
self.Deployment=V[3]
self.user=0
class Sever_Machine:
def __init__(self,Sever):
self.Model=Sever[0] #型号
self.CPU_cores=Sever[1] #CPU核数
self.Memory_Size=Sever[2] #内存大小
self.Hardware_cost=Sever[3] #硬件成本
self.Energy_cost=Sever[4] #能耗成本
self.Node_A=[] #当前A节点剩余核数内存情况
self.Node_B=[] #当前B节点剩余核数内存情况
self.Both=[]
self.assigned=[]
self.assigned_Node=[]
self.rest_CPU_A=self.CPU_cores/2
self.rest_Memory_A=self.Memory_Size/2
self.rest_CPU_B = self.CPU_cores/2
self.rest_Memory_B = self.Memory_Size/2
def add_to_Node_A(self,V):
self.Node_A.append(V)
self.assigned.append(V.user)
self.assigned_Node.append(1)
self.rest_CPU_A -= V.CPU_cores
self.rest_Memory_A -= V.Memory_Size
def add_to_Node_B(self,V):
self.Node_B.append(V)
self.assigned.append(V.user)
self.assigned_Node.append(2)
self.rest_CPU_B -= V.CPU_cores
self.rest_Memory_B -= V.Memory_Size
def add_to_both(self,V):
self.Both.append(V)
self.assigned.append(V.user)
self.assigned_Node.append(0)
self.rest_CPU_A-=V.CPU_cores/2
self.rest_Memory_A-=V.Memory_Size/2
self.rest_CPU_B -= V.CPU_cores / 2
self.rest_Memory_B -= V.Memory_Size / 2
def Judge_whether_to_insert(self,V):
C=V.CPU_cores
M=V.Memory_Size
A=self.rest_CPU_A
B=self.rest_Memory_A
C=self.rest_CPU_B
D=self.rest_Memory_B
K=[]
if V.Deployment==1:
if self.rest_CPU_A>=V.CPU_cores/2 and self.rest_CPU_B>=V.CPU_cores/2 and\
self.rest_Memory_A>=V.Memory_Size/2 and self.rest_Memory_B>=V.Memory_Size/2:
self.add_to_both(V)
return True
else:
return False
if V.Deployment==0:
if self.rest_CPU_A>=V.CPU_cores and self.rest_Memory_A>=V.Memory_Size :
K.append(1)
if self.rest_CPU_B >= V.CPU_cores and self.rest_Memory_B >=V.Memory_Size:
K.append(2)
if len(K)==2:
if random.choice(K)==1:
self.add_to_Node_A(V)
else:
self.add_to_Node_B(V)
return True
elif len(K)==1:
if K==1:
self.add_to_Node_A(V)
else:
self.add_to_Node_B(V)
return True
else:
return False
def del_Virtual(self,V):
K=self.assigned.index(V.user)
M=self.assigned_Node[K]
if M==0:
self.rest_CPU_A += V.CPU_cores
self.rest_Memory_A += V.Memory_Size
if M==1:
self.rest_CPU_B += V.CPU_cores
self.rest_Memory_B += V.Memory_Size
if M==0:
self.rest_CPU_A += V.CPU_cores / 2
self.rest_Memory_A += V.Memory_Size / 2
self.rest_CPU_B += V.CPU_cores / 2
self.rest_Memory_B += V.Memory_Size / 2
self.assigned.remove(K)
del self.assigned_Node[K]
def Node_Situation(self):
Load_CPU_A=self.CPU_cores/2-self.rest_CPU_A
Load_CPU_B=self.CPU_cores/2-self.rest_CPU_B
Load_M_A=self.Memory_Size/2-self.rest_Memory_A
Load_M_B=self.Memory_Size/2-self.rest_Memory_B
return Load_CPU_A,Load_CPU_B,Load_M_A,Load_M_B
def Use_situation(self):
Load_CPU= self.CPU_cores - self.rest_CPU_A-self.rest_CPU_A
Load_M = self.Memory_Size - self.rest_Memory_A- self.rest_Memory_B
return Load_CPU,Load_M
def replace_machine(self,Sev):
self.Model = Sev[0] # 型号
self.CPU_cores = Sev[1] # CPU核数
self.Memory_Size = Sev[2] # 内存大小
self.Hardware_cost = Sev[3] # 硬件成本
self.Energy_cost = Sev[4] # 能耗成本
class daily_situation:
def __init__(self,Sever,Virtual,use_Case):
self.Sever=Sever
self.Virtual=Virtual
self.use_Case=use_Case
self.days=0.2*(len(use_Case))
def Sever_Select(self,K):
V=copy.copy(K)
Selected_Sever = []
Select = random.choice(self.Sever)
Select_i = Sever_Machine(Select)
while V != []:
Select_V =random.choice(V)
result = Select_i.Judge_whether_to_insert(Select_V)
if result == True: # 随机配置
V.remove(Select_V)
if V==[]:
Selected_Sever.append(Select_i)
break
if result == False:
for i in range(len(V)):
result = Select_i.Judge_whether_to_insert(V[i])
if result == True:
V.remove(V[i])
break
if result == False and i >= len(V) - 1:
Selected_Sever.append(Select_i)
Select = random.choice(self.Sever)
Select_i = Sever_Machine(Select)
return Selected_Sever
return Selected_Sever
def add_to_old(self,S,V):
for i in range(len(S)):
if V!=[]:
random.shuffle(V)
for V_i in V:
result=S[i].Judge_whether_to_insert(V_i)
if result==True:
V.remove(V_i)
return S,V
def transfer(self,Sever,V_total):
Transferable_num = int(len(V_total) * 5 / 1000)
if Transferable_num>0:
# for i in range(len())
pass
else:
pass
return Sever
def Virtual_use(self):
Selected_Sever=[]
V_total=[]
for i in range(len(self.use_Case)):
V_T = []
for j in range(len(self.use_Case[i])):
if self.use_Case[i][j][0] == 'add':
for V_i in range(len(self.Virtual)):
if self.use_Case[i][j][1] == self.Virtual[V_i][0]:
V_I = Virtual_Machine(self.Virtual[V_i], self.use_Case[i][j][2])
V_T.append(V_I)
V_total.append(V_I)
break
if self.use_Case[i][j][0] == 'del':
for V_k in range(len(V_total)):
if V_total[V_k].user == self.use_Case[i][j][1]:
V_total.remove(V_total[V_k])
for S_i in range(len(Selected_Sever)):
if V_total[V_k].user in Selected_Sever[S_i].assigned:
Selected_Sever[S_i].del_Virtual(V_total[V_k])
break
break
K = copy.copy(V_T)
if Selected_Sever==[]:
d = GA()
Selected_Sever = d.main(K, self.Sever, len(self.use_Case) - i)
Q=[]
for i in range(len(Selected_Sever)):
Q.append(Selected_Sever[i].Model)
Q_set=set(Q)
Q_num=len(list(Q_set))
print('(Purchase,', Q_num, ')')
for Q_i in Q_set:
print('(',Q_i,',', Q.count(Q_i), ')')
print('(migration,', 0, ')')
New_order=[]
for Si in Q_set:
for Sv in Selected_Sever:
if Sv.Model==Si:
New_order.append(Sv)
Selected_Sever=New_order
for u_i in V_T:
for S_v in range(len(Selected_Sever)):
if u_i.user in Selected_Sever[S_v].assigned:
if Selected_Sever[S_v].assigned_Node[Selected_Sever[S_v].assigned.index(u_i.user)]==1:
print('(',S_v,',','A' , ')')
if Selected_Sever[S_v].assigned_Node[Selected_Sever[S_v].assigned.index(u_i.user)]==2:
print('(',S_v,',','B' , ')')
if Selected_Sever[S_v].assigned_Node[Selected_Sever[S_v].assigned.index(u_i.user)]==0:
print('(',S_v, ')')
else:
Add=self.add_to_old(Selected_Sever,K)
Old_Sever=Add[0]
rest_V=Add[1]
d = GA()
Selected_Sever_1 = d.main(rest_V, self.Sever, len(self.use_Case) - i)
Q = []
for i in range(len(Selected_Sever_1)):
Q.append(Selected_Sever_1[i].Model)
Q_set = set(Q)
Q_num = len(list(Q_set))
print('(Purchase,', Q_num, ')')
for Q_i in Q_set:
print('(', Q_i, ',', Q.count(Q_i), ')')
print('(migration,', 0, ')')
New_order = []
for Si in Q_set:
for Sv in Selected_Sever_1:
if Sv.Model == Si:
New_order.append(Sv)
Selected_Sever.extend(New_order)
for u_i in V_T:
for S_v in range(len(Selected_Sever)):
if u_i.user in Selected_Sever[S_v].assigned:
if Selected_Sever[S_v].assigned_Node[Selected_Sever[S_v].assigned.index(u_i.user)]==1:
print('(',S_v,',','A' , ')')
if Selected_Sever[S_v].assigned_Node[Selected_Sever[S_v].assigned.index(u_i.user)]==2:
print('(',S_v,',','B' , ')')
if Selected_Sever[S_v].assigned_Node[Selected_Sever[S_v].assigned.index(u_i.user)]==0:
print('(',S_v, ')')
def Get_data(path):
if os.path.exists(path):
with open(path,'r') as data:
Lis=data.readlines()
Sever=[]
Virtual=[]
counter=0
use_Case=[]
while Lis:
num=Lis[0].strip().split('\n')[0]
if num.isdigit():
Lis=Lis[1:len(Lis)]
last_num=int(num)
else:
add_sentence=Lis[0:last_num]
P=[]
for i in range(len(add_sentence)):
P_1=[]
sentence = add_sentence[i]
result=re.findall(r'[a-zA-Z0-9.]{1,}',sentence)
for r_i in result:
if r_i.isdigit():
P_1.append(int(r_i))
else:
P_1.append(r_i)
P.append(P_1)
if counter==0:
Sever=P
if counter==1:
Virtual=P
if counter>1:
use_Case.append(P)
counter+=1
Lis=Lis[last_num:len(Lis)]
return Sever,use_Case,Virtual
def main():
# to read standard
A = Get_data('training-1.txt')
# process
d=daily_situation(A[0],A[2],A[1])
d.Virtual_use()
# to write standard output
# sys.stdout.flush()
if __name__ == "__main__":
S=time.time()
main()
E=time.time()
print(E)
输出: