2021华为软挑初探——代码实现

其他工作:

2021华为软挑部分答疑——哪些你有错却总是找不到的地方,我来带你找啦(含标准输入代码)

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)

输出:

 

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码丽莲梦露

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值