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

本篇主要介绍如何利用遗传算法实现移动边缘环境下(或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 jEdgetime2[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()
工作负荷

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

你可能感兴趣的:(基于遗传算法的移动边缘计算环境下服务工作流的计算卸载)