基于遗传算法的移动边缘计算环境下服务工作流的计算卸载

本篇主要介绍如何利用遗传算法实现移动边缘环境下(或5G环境下)移动设备工作流的计算卸载问题,详见董浩等文章《移动边缘计算环境下服务工作流的计算卸载》。
简单介绍:
  实际应用环境为在移动边缘计算平台中,移动设备连接到基站,以从边缘服务器建立和部署服务。当移动用户执行计算工作流程时,可以通过移动网络将工作流程的服务卸载到边缘服务器。在边缘云中,边缘服务器接收来自移动用户的请求并在适当的时候处理它们。然后通过移动网络返回给移动用户。在这项工作中,假设所有服务都可以在本地运行或卸载到边缘服务器。
  研究目标是在移动边缘环境下,同时对移动终端设备在处理任务时电池的总能耗和任务的总完成时间进行多目标优化。针对这一问题,重点设计一种智能算法来对此进行优化。由于优化这些目标需要考虑的方面很多,因此优化时先考虑单边缘端计算情况,再将结论推广至多个移动设备和多个移动边缘端的情形。
  遗传算法是一种模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程中的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。它是一种基于“适者生存”的高度并行、随机和自适应的优化算法,通过复制、交叉、变异将问题解编码表示的“染色体”群一代代不断进化,最终收敛到最适应的群体,从而求得问题的最优解和满意解。
  因此尝试使用基于遗传算法的方法定制成解决本研究问题移动边缘计算工作流调度多目标优化的算法。为了体现算法的优越性,需要与完全本地执行算法(Local Execution)和随机执行算法(RANDOM)的结果进行对比。完全本地执行算法就是将所有任务都放在移动设备上进行执行处理。随机执行算法就是对于任务的执行位置(即资源的匹配)和排序都采用随机的方式。综上所述,研究的重点内容包含以下两个方面:
  1. 提出一种结合工作流调度的新型卸载策略,其组件之间具有相互依赖关系。
  2. 设计并实现基于遗传算法的优化方法来做卸载决策。

再上几张图把问题展示的更清楚:


移动边缘计算

工作流调度优化

目标函数或称为适应度函数

遗传算法流程

主函数如下:

#导入自定义的模块
import plot_fitness_by_task_amout as pfbta
import plot_fitness_by_datasize as pfbd
import plot_fitness_by_workload as pfbw
import plot_fitness_by_iteration as pfbi
#根据文章实验要求进行绘图,分别为任务量、输出数据大小、工作量、迭代次数
pfbta.plot_fitness_by_task_amout()
pfbd.plot_fitness_by_datasize()
pfbw.plot_fitness_by_workload()
pfbi.plot_fitness_by_iteration()

参数设置:

#导入相关模块
import copy
import random
import numpy as np
import taskinitial as ti
import matplotlib.pyplot as plt
#全局参数设置
flow_num=1#本以为文章提到的N=50为任务流50个,后发现指在遗传算法中备选染色体个数,在本次仿真中用不上,设为1即可
task_num=50#每个任务流中含有task_num个任务,对应遗传算法编码长度为task_num
c_M=1#移动设备计算能力
P_M=0.5#本地工作时,设备功耗
P_up=0.1#上传时,设备功耗
P_down=0.1#下载时,设备功耗
c_E=3#边缘处理能力
Omiga=0.5#目标函数权重参数,当移动设备的电池充满时,增大;当其能量下降到阈值以下时,降低。
Up_Speed=8#上传速度未知,根据仿真的情况单位应为Mb
Down_Speed=8#下载速度未知,根据仿真的情况单位应为Mb

任务初始化

#*******************************************************************************
#初始化模块,用于生成任务流的位置、排序
#*******************************************************************************
import random
import numpy as np
#1.任务位置随机初始化,参考论文算法1
def Position_intial(N,n,X_):
    for i in range(N):
        for j in range(n):
            X_[i][j]=random.random()
    #大于0.5为1,小于0.5为0
    X_=np.int32(X_>0.5)
    return X_

#2.产生具有一定顺序的任务流,记录前驱任务Pre_task_dict和后驱任务Sub_task_dict
def Order_initial(n):
    Pre_task_dict=dict()
    Sub_task_dict=dict()
    Pre_task_dict[1]=[]#第一个任务先放进前驱任务列字典中,其前驱任务为空
    Task_order=[1]#第一个任务先放进任务列表中
    task_previous=[1]#第一个任务先放进前驱任务列列表中
    Y_list=list(range(2,n+1))
          
    while Y_list:
        #在剩下的任务中随机选择random_temp_num个任务
        random_temp_num=np.random.randint(1,len(Y_list)+1)
        task_temp=random.sample(Y_list,random_temp_num)
        #为每个任务随机生成前驱任务
        for j in range(len(task_temp)):
            random_previous_num=np.random.randint(1,len(task_previous)+1)
            task_previous_temp=random.sample(task_previous,random_previous_num)
            #保存前驱任务字典
            Pre_task_dict[task_temp[j]]=task_previous_temp
            Y_list.remove(task_temp[j])
        task_previous=task_temp
        Task_order=Task_order+task_temp

    #找出后驱任务,保存进字典
    for key1 in range(1,n+1):
        temp=[]
        for key2 in range(1,n+1):
            if key1 in Pre_task_dict[key2]:
                temp.append(key2)
        Sub_task_dict[key1]=temp
    return Task_order,Pre_task_dict,Sub_task_dict

#3.在既定的随机任务顺序下,再次进行随机初始化,参考论文算法2
def Order_re_initial(Original,Prelist,WorkLoad,OutputSize):
    R=[]
    S=[]
    R.append(Original[0])
    S=list(Original[1:])
    WorkLoad_New=np.zeros((WorkLoad.shape))
    OutputSize_New=np.zeros((OutputSize.shape))
    while S:
        E=[]
        for i in range(len(S)):
            if set(Prelist[S[i]]).issubset(set(R)) and S[i] not in E:#Pre如何确定?
                E.append(S[i])
        s_index=random.choice(E)
        R.append(s_index)#随机选取,加入排序列表
        E.remove(s_index)
        S.remove(s_index)
    for i in range(len(R)):
        k=int(np.where(Original==R[i])[0])#原来的位置
        WorkLoad_New[0,i]=WorkLoad[0,k]
        OutputSize_New[0,i]=OutputSize[0,k]
    return R,WorkLoad_New,OutputSize_New

LOCAL算法:

#LOCAL算法
from parameters import *
def Local_Fitness(WorkLoad,task_num,flow_num):
    Local_time=np.zeros((flow_num,task_num))
    Local_energy=np.zeros((flow_num,task_num))
    for i in range(flow_num):
        for j in range(task_num):
            Local_time[i,j]=WorkLoad[i,j]/c_M
            Local_energy[i,j]=Local_time[i,j]*P_M
    Time=Local_time.sum()/flow_num
    Energy=Local_energy.sum()/flow_num
    Fitness_Value=0.5*Time+0.5*Energy
    return Fitness_Value 

RANDOM算法:

#Random算法
#**********************************************************************************
#随机算法,也可看做是求解的目标函数的过程,分别求以下几个部分
#1.本地时间:本地服务器处理数据时间
#2.卸载服务时间:(1)上传(输入)数据时间,(2)边缘服务器处理数据时间,(3)下载(输出)数据时间
#3.本地能耗:本地数据处理能耗
#4.边缘能耗:上传及下载能耗
#**********************************************************************************
#导入参数库
from parameters import *
#定义随机算法函数
def Random_Fitness(Location,Sequence,PreTask,SubTask,WorkLoad,OutputSize,task_num,flow_num):
    #定义各种中间数组
    para_point=np.ones((flow_num,1))*(task_num+1)#并行点初始化为0
    Up_Size=np.zeros((flow_num,task_num))#上传数据大小
    Down_Size=np.zeros((flow_num,task_num))#下载数据大小
    Localtime1=np.zeros((flow_num,1))#并行点前本地时间
    Localtime2=np.zeros((flow_num,1))#并行点后本地时间
    Edgetime1=np.zeros((flow_num,1))#并行点前边缘时间
    Edgetime2=np.zeros((flow_num,1))#并行点后边缘时间
    Local_energy=np.zeros((flow_num,1))#本地能耗
    Edge_energy=np.zeros((flow_num,1))#边缘能耗
    Fitness_Value =np.zeros((flow_num,1))#目标函数(适应度函数)值

    #找出第一个可以并行的点,即任务流中两个连续的任务编码不相同(一个是0,另一个是1),并且前一个非后一个的前驱任务
    for i in range(flow_num):
        for j in range(task_num):
            if j+1!=task_num and Location[i,j]!=Location[i,j+1] and Sequence[i,j] not in PreTask[i][Sequence[i,j+1]]:
                para_point[i,0]=j
                break
    #计算上传和下载数据大小
    for i in range(flow_num):
        for j in range(task_num):
            #计算本地上传到边缘端的数据大小,将每个任务的前驱任务中的本地任务输出数据求和
            #Up_Size数组保存每个任务前驱任务中本地任务的输出数据和,用来计算上传时间
            if Location[i,j]==1:#发生数据传输必定是在边缘端
                for item in PreTask[i][Sequence[i,j]]:#遍历每个边缘端的任务的前驱任务
                    k=int(np.where(Sequence[i]==item)[0])#定位每个前驱任务的下标,方便进行数据量查询
                    if Location[i,k]==0:#如果这个前驱任务的在本地执行才需要进行数据传输
                        Up_Size[i,j]=Up_Size[i,j]+OutputSize[i,k]#将满足条件的前驱任务的数据量求和
                #计算边缘端下载到本地的数据大小,如果某个任务的后驱任务中有本地任务,则将该任务输出数据求和
                #Down_Size数组保存某个满足条件的任务输出数据和,用来计算上传时间
                for item in SubTask[i][Sequence[i,j]]:#遍历每个边缘端的任务的后驱任务
                    k=int(np.where(Sequence[i]==item)[0])#定位每个后驱任务的下标,方便进行数据量查询
                    if Location[i,k]==0:#如果这个前驱任务的在本地执行才需要进行数据传输
                        Down_Size[i,j]=Down_Size[i,j]+OutputSize[i,j]#将满足条件的前驱任务的数据量求和

    #上传时间等于上传数据除以上传速度,下载时间等与下载数据除以下载速度
    Up_time=copy.deepcopy(Up_Size/Up_Speed)
    Down_time=copy.deepcopy(Down_Size/Down_Speed)
    #分别计算本地和边缘端时耗            
    for i in range(flow_num):
        for j in range(task_num):
            #如果在并行点之前,本地时间等于工作量除以本地服务器处理能力,边缘时间等于上传时间+下载时间+工作量/边缘服务器处理能力
            if j<para_point[i,0]:
                if Location[i,j]==0:
                    Localtime1[i,0]=Localtime1[i,0]+WorkLoad[i,j]/c_M#公式(2)
                else:
                    Edgetime1[i,0]=Edgetime1[i,0]+Up_time[i,j]+WorkLoad[i,j]/c_E+Down_time[i,j]#公式(4)
            #如果在并行点之后,时间计算如上
            else:
                if Location[i,j]==0:
                    Localtime2[i,0]=Localtime2[i,0]+WorkLoad[i,j]/c_M
                else:
                    Edgetime2[i,0]=Edgetime2[i,0]+Up_time[i,j]+WorkLoad[i,j]/c_E+Down_time[i,j]
        #能耗计算
        Local_energy[i,0]=(Localtime1[i,0]+Localtime2[i,0])*P_M#公式(3)
        Edge_energy[i,0]=Up_time.sum()*P_up+Down_time.sum()*P_down#公式(5)
        #比较并行点之后,本地运行时长和边缘运行时长,哪个长就用它加上并行点前面的本地时间和边缘时间作为最终的时长
        if Localtime2[i,0]>Edgetime2[i,0]:
            Fitness_Value[i,0] =Omiga*(Localtime1[i,0]+Edgetime1[i,0]+Localtime2[i,0])+Omiga*(Local_energy[i,0]+Edge_energy[i,0])
        else:
            Fitness_Value[i,0] =Omiga*(Localtime1[i,0]+Edgetime1[i,0]+Edgetime2[i,0])+Omiga*(Local_energy[i,0]+Edge_energy[i,0])
    return Fitness_Value.sum()/flow_num

遗传算法(部分):

#遗传算法
#*********************************************************************************************
#对于给定的一个任务流,在遵守任务前后顺序下,存在不同的位置编码和不同的排序编码
#比如对于任务流S,可以通过初始化得到N个位置编码,N个排序编码
    #1.调用Order_initial生成一个带前后固定顺序(即前驱任务固定)的任务流
    #2.调用N次Position_initial生成N个任务位置编码,可能存在重复
    #3.调用N次Order_re_initial生成N个重新排序的任务排序编码,可能存在重复
    #4.遗传算法执行过程
            #(1)对每一组(位置,排序)进行适应度函数测试,如果终止条件满足,则退出。否则执行步骤如下:
            #(2)利用轮盘赌方法,选择两个适应度较高的个体
            #(3)对这两个个体的位置和排序分别进行交叉操作得到新的两个个体
            #(4)对交叉得到的新的两个个体进行位置和排序进行变异操作
            #(5)计算两个新个体的适应度值,如果比现有的个体适应度低则进行替换,有几个换几个
            #(6)否则返回第(1)步
#终止条件可以有以下几种:(1)达到迭代次数;(2)达到目标;(3)与前一次比不在发再明显变化;本仿真采用第1种
#*********************************************************************************************
#导入相应的库
from parameters import *
import random_algorithm as ra#用于计算RANDOM和GA算法的适应度
import local_algorithm as la#用于计算LOCAL算法的适应度

#如果终止条件不满足,利用轮盘赌算法实现找出根据概率找出两个适应度较小的染色体
def RouletteWheelSelection(genetic_fitness_list):#genetic_fitness_list为第(1)步得到的适应度列表
    #计算适应度总和与每个适应度的比例,由于本文要求适应度越低越好,所以是反着来
    max_fitness=np.max(genetic_fitness_list)

画图函数1:

#******************************************************************
#根据输出数据大小变化画图,本例子任务量分别取[5,10,15,20,25]
#******************************************************************
#导入相关库
from parameters import *
import local_algorithm as la
import random_algorithm as ra
import genetic_algorithm as ga

def plot_fitness_by_datasize():
    
    #定义三个列表,分别用来保存不同任务量前提下,LOCAL,RANDOM,GA算法得到的适应度值
    local_fitnesses_list=[];random_fitnesses_list=[];genetic_fitnesses_list=[]

    #随机生成一个任务流,并保存前驱任务和后驱任务
    Task_order,Pre_task_dict,Sub_task_dict=ti.Order_initial(task_num)

    #由于前期coding的遗害,需要将前驱任务和后驱任务保存为一个列表,其值为一个字典
    Pre_task=[];Sub_task=[];Pre_task.append(Pre_task_dict);Sub_task.append(Sub_task_dict)

    #随机生成10个位置编码,与即将生成的10个排序对应
    Ga_initial_location=np.zeros((10,task_num))
    Ga_initial_location=ti.Position_intial(10,task_num,Ga_initial_location)

    #由于用到了遗传算法,所以需要先进行初始化
    Ga_initial_sequence=np.int32(np.zeros((10,task_num)))
    
    #生成这个工作流中每个任务对应的工作量和输出数据大小
    WorkLoad=np.random.uniform(1,100,(1,task_num))#工作量
    WorkLoad_initial=np.zeros((10,task_num))
    OutputSize_initial=np.zeros((10,task_num))
    OutputSize=np.ones((1,task_num))

    #再遵循任务流依赖关系,生成10个排序编码,工作量编码和输出量编码
    for j in range(10):
        Ga_initial_sequence[j],WorkLoad_initial[j],OutputSize_initial[j]=ti.Order_re_initial(np.array(Task_order),Pre_task_dict,WorkLoad,OutputSize)
        

    for i in range(5,26,5):
        print("--------------------------输出数据大小为",i,"Mb时:--------------------------")
        #给OutputSize重新赋值,分别取[5,10,15,20,25]
        for j in range(10):
            OutputSize_initial[j]=np.ones((1,task_num))*i#输出数据
        
        #深度拷贝,记住数组不能直接用“=”来进行复制
        Ga_workload=copy.deepcopy(WorkLoad_initial)
        Ga_location=copy.deepcopy(Ga_initial_location)
        Ga_sequence=copy.deepcopy(Ga_initial_sequence)
        Ga_outputsize=copy.deepcopy(OutputSize_initial)

        #调用遗传算法,输出LOCAL,RANDOM,GA算法的适应度值
        local_fitness,random_fitness,genetic_fitness=ga.Genetic_Fitness(Ga_location,Ga_sequence,Pre_task,Sub_task,Ga_workload,Ga_outputsize,task_num,10)
        
        local_fitnesses_list.append(local_fitness)
        random_fitnesses_list.append(random_fitness)
        genetic_fitnesses_list.append(genetic_fitness)

    plt.plot(list(range(5,26,5)),local_fitnesses_list,'r-o',list(range(5,26,5)),random_fitnesses_list,'b-^',list(range(5,26,5)),genetic_fitnesses_list,'g-s')
    plt.legend(('LOCAL', 'RANDOM','GA'), loc='best')
    plt.xlabel('DataSize')
    plt.ylabel('Fitness')
    plt.ylim(bottom=0)
    plt.show()
数据大小

画图函数2:

#******************************************************************
#根据迭代数变化画图,本例子迭代次数分别取[10,20,30,40,50]
#******************************************************************

#导入相关库
from parameters import *
import local_algorithm as la
import random_algorithm as ra
import genetic_algorithm as ga


def plot_fitness_by_iteration():

    #定义三个分别用来保存不同任务量前提下,LOCAL,RANDOM,GA算法得到的适应度值
    local_fitnesses_list=[];random_fitnesses_list=[];genetic_fitnesses_list=[]
    
    #随机生成一个任务流,并保存前驱任务和后驱任务
    Task_order,Pre_task_dict,Sub_task_dict=ti.Order_initial(task_num)

    #前驱任务和后驱任务保存为一个列表,其值为一个字典
    Pre_task=[];Sub_task=[];Pre_task.append(Pre_task_dict);Sub_task.append(Sub_task_dict)

    #随机生成50个位置编码,对应50个排序,而不是50个工作流
    Ga_initial_location=np.zeros((10,task_num))
    Ga_initial_location=ti.Position_intial(10,task_num,Ga_initial_location)

    #由于用到了遗传算法,所以需要先进行初始化
    Ga_initial_sequence=np.int32(np.zeros((10,task_num)))
    WorkLoad_initial=np.zeros((10,task_num))
    OutputSize_initial=np.zeros((10,task_num))

    #生成该任务流中每个任务对应的输出数据大小
    OutputSize=np.random.uniform(1,25,(1,task_num))#输出数据大小
    WorkLoad=np.random.uniform(1,100,(1,task_num))#工作量

    #再遵循任务流依赖关系,生成10个排序编码,工作量编码和输出量编码
    for j in range(10):
        Ga_initial_sequence[j],WorkLoad_initial[j],OutputSize_initial[j]=ti.Order_re_initial(np.array(Task_order),Pre_task_dict,WorkLoad,OutputSize)

    #迭代次数为[10,20,30,40,50]
    for i in range(10,51,10):
        print("--------------------------迭代数为",i,"时:--------------------------")

        #深度拷贝,记住数组不能直接用“=”来进行复制
        Ga_workload=copy.deepcopy(WorkLoad_initial)
        Ga_location=copy.deepcopy(Ga_initial_location)
        Ga_sequence=copy.deepcopy(Ga_initial_sequence)
        Ga_outputsize=copy.deepcopy(OutputSize_initial)
        
        #调用遗传算法,输出LOCAL,RANDOM,GA算法的适应度值
        local_fitness,random_fitness,genetic_fitness=ga.Genetic_Fitness(Ga_location,Ga_sequence,Pre_task,Sub_task,Ga_workload,Ga_outputsize,task_num,i)     
        
        local_fitnesses_list.append(local_fitness)
        random_fitnesses_list.append(random_fitness)
        genetic_fitnesses_list.append(genetic_fitness)

    plt.plot(list(range(10,51,10)),random_fitnesses_list,'r-^',list(range(10,51,10)),genetic_fitnesses_list,'g-s')
    plt.legend(('RANDOM',"GA"), loc='best')
    plt.xlabel('Iteration')
    plt.ylabel('Fitness')
    # plt.xlim(left=10)
    plt.ylim(bottom=0)
    plt.show()
迭代次数

画图函数3:

#******************************************************************
#根据任务量变化画图,本例子任务量分别取[10,20,30,40,50]
#******************************************************************
#导入相关库
from parameters import *
import local_algorithm as la
import random_algorithm as ra
import genetic_algorithm as ga

#画图函数
def plot_fitness_by_task_amout():
    #定义三个列表,分别用来保存不同任务量前提下,LOCAL,RANDOM,GA算法得到的适应度值
    local_fitnesses_list=[];random_fitnesses_list=[];genetic_fitnesses_list=[]
    
    for i in range(50,251,50):
        print("--------------------------任务数为",i,"时:--------------------------")
        task_num=i
        #随机生成一个任务流,并保存前驱任务和后驱任务
        Task_order,Pre_task_dict,Sub_task_dict=ti.Order_initial(task_num)

        #前驱任务和后驱任务保存为一个列表,其值为一个字典
        Pre_task=[];Sub_task=[];Pre_task.append(Pre_task_dict);Sub_task.append(Sub_task_dict)

        #随机生成10个位置编码,对应10个排序,而不是10个工作流
        Ga_initial_location=np.zeros((10,task_num))
        Ga_initial_location=ti.Position_intial(10,task_num,Ga_initial_location)

        #生成这个工作流中每个任务对应的工作量和输出数据大小
        WorkLoad=np.random.uniform(1,100,(1,task_num))#工作量
        OutputSize=np.random.uniform(1,25,(1,task_num))#输出数据大小

        #由于用到了遗传算法,所以需要先进行初始化
        Ga_initial_sequence=np.int32(np.zeros((10,task_num)))
        WorkLoad_initial=np.zeros((10,task_num))
        OutputSize_initial=np.zeros((10,task_num))

        #再遵循任务流依赖关系,生成10个排序编码,工作量编码和输出量编码
        for j in range(10):
            Ga_initial_sequence[j],WorkLoad_initial[j],OutputSize_initial[j]=ti.Order_re_initial(np.array(Task_order),Pre_task_dict,WorkLoad,OutputSize)
        
        #调用遗传算法,输出LOCAL,RANDOM,GA算法的适应度值
        local_fitness,random_fitness,genetic_fitness=ga.Genetic_Fitness(Ga_initial_location,Ga_initial_sequence,Pre_task,Sub_task,WorkLoad_initial,OutputSize_initial,task_num,10)
        local_fitnesses_list.append(local_fitness)
        random_fitnesses_list.append(random_fitness)
        genetic_fitnesses_list.append(genetic_fitness)

    plt.plot(list(range(50,251,50)),local_fitnesses_list,'r-o',list(range(50,251,50)),random_fitnesses_list,'b-^',list(range(50,251,50)),genetic_fitnesses_list,'g-s')
    plt.legend(('LOCAL', 'RANDOM','GA'), loc='best')
    plt.xlabel('Task Amount')
    plt.ylabel('Fitness')
    plt.ylim(bottom=0)
    plt.show()
任务量

画图函数4:

#******************************************************************
#根据工作量变化画图,本例子工作负荷分别取[20,40,60,80,100]
#******************************************************************

#导入相关库
from parameters import *
import local_algorithm as la
import random_algorithm as ra
import genetic_algorithm as ga

#画图函数
def plot_fitness_by_workload():

    #定义三个分别用来保存不同任务量前提下,LOCAL,RANDOM,GA算法得到的适应度值
    local_fitnesses_list=[];random_fitnesses_list=[];genetic_fitnesses_list=[]
    
    #随机生成一个任务流,并保存前驱任务和后驱任务
    Task_order,Pre_task_dict,Sub_task_dict=ti.Order_initial(task_num)

    #由于前期coding的遗害,需要将前驱任务和后驱任务保存为一个列表,其值为一个字典
    Pre_task=[];Sub_task=[];Pre_task.append(Pre_task_dict);Sub_task.append(Sub_task_dict)

    #随机生成10个位置编码,与即将生成的10个排序对应
    Ga_initial_location=np.zeros((10,task_num))
    Ga_initial_location=ti.Position_intial(10,task_num,Ga_initial_location)

    #由于用到了遗传算法,所以需要先进行初始化
    Ga_initial_sequence=np.int32(np.zeros((10,task_num)))

    WorkLoad_initial=np.zeros((10,task_num))
    OutputSize_initial=np.zeros((10,task_num))

    #生成该任务流中每个任务对应的输出数据大小
    OutputSize=np.random.uniform(1,25,(1,task_num))#输出数据大小
    WorkLoad=np.ones((1,task_num))

    #再遵循任务流依赖关系,生成10个排序编码,工作量编码和输出量编码
    for j in range(10):
        Ga_initial_sequence[j],WorkLoad_initial[j],OutputSize_initial[j]=ti.Order_re_initial(np.array(Task_order),Pre_task_dict,WorkLoad,OutputSize)
    
    for i in range(20,101,20):
        print("--------------------------工作量为",i,"时:--------------------------")
        #给Workload重新赋值,分别取[20,40,60,80,100]
        for j in range(10):
            WorkLoad_initial[j]=np.ones((1,task_num))*i#工作量

        #深度拷贝,记住数组不能直接用“=”来进行复制
        Ga_workload=copy.deepcopy(WorkLoad_initial)
        Ga_location=copy.deepcopy(Ga_initial_location)
        Ga_sequence=copy.deepcopy(Ga_initial_sequence)
        Ga_outputsize=copy.deepcopy(OutputSize_initial)

        #调用遗传算法,输出LOCAL,RANDOM,GA算法的适应度值
        local_fitness,random_fitness,genetic_fitness=ga.Genetic_Fitness(Ga_location,Ga_sequence,Pre_task,Sub_task,Ga_workload,Ga_outputsize,task_num,10)
        
        local_fitnesses_list.append(local_fitness)
        random_fitnesses_list.append(random_fitness)
        genetic_fitnesses_list.append(genetic_fitness)

    plt.plot(list(range(20,101,20)),local_fitnesses_list,'r-o',list(range(20,101,20)),random_fitnesses_list,'b-^',list(range(20,101,20)),genetic_fitnesses_list,'g-s')
    plt.legend(('LOCAL', 'RANDOM',"GA"), loc='best')
    plt.xlabel('WorkLoad')
    plt.ylabel('Fitness')
    plt.ylim(bottom=0)
    plt.show()
工作负荷

需要遗传算法完整代码,请留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 7月4日,在2019百度AI开发者大会上,百度携手三大运营商、浪潮、英特尔等联合发布了百度AI边缘计算行动计划和《...
    边缘计算社区阅读 1,055评论 0 6
  • 下周二三,难得的双休,好好把握,出去浪一下
    揭森阅读 147评论 0 0
  • 在自己心爱的男人的背上,小兰双手环着小风的脖子,整个脸贴在了小风的背上,不由的闭上了眼睛。 长长的睫毛在轻地动着,...
    禅茶语惑阅读 536评论 0 2
  • 结束学习时间是16号,到今天大概14天。曾经我以为我能量已经被拉得很高了,没有想着这么快就跌到负数的地步。 ...
    幸福猪2023阅读 120评论 0 1
  • 任何事情都会有始有终。今天是我们在敦煌的最后一天,今天我们去参观了莫高窟,那是敦煌的精华。 莫高窟,又称千佛...
    初二3班杨英杰阅读 253评论 0 0