예제 #1
0
    def Plot_Save(self):
        self.best_gen = np.argmax(self.obj_trace[:, [1]])
        self.best_Objv = self.obj_trace[self.best_gen, 1]
        self.best_chrom_i = self.var_trace[self.best_gen]

        # pdb.set_trace()
        ea.trcplot(trace=self.obj_trace,
                   labels=[['POP Mean Objv', 'Best Chrom i Objv']],
                   titles=[['Mean_Best_Chromi_Objv']],
                   save_path=self.cfg.PARA.CNN_params.save_data_path,
                   xlabels=[['GEN']],
                   ylabels=[['ACC']])

        with open(self.cfg.PARA.CNN_params.save_bestdata_txt, 'a') as f:
            f.write('best_Objv=%.5f,best_chrom_i=%s,total_time=%.5f\n' %
                    (self.best_Objv, str(self.best_chrom_i), self.time))

        np.savetxt(
            self.cfg.PARA.CNN_params.save_data_path + 'MeanChromi_Objv.txt',
            self.obj_trace[:, 0])
        np.savetxt(
            self.cfg.PARA.CNN_params.save_data_path + 'BestChromi_Objv.txt',
            self.obj_trace[:, 1])
        np.savetxt(self.cfg.PARA.CNN_params.save_data_path + 'BestChromi.txt',
                   self.var_trace)
예제 #2
0
 def run(self):
     #==========================初始化配置===========================
     population = self.population
     NIND = population.sizes
     NVAR = self.problem.Dim  # 得到决策变量的个数
     self.obj_trace = (np.zeros(
         (self.MAXGEN, 2)) * np.nan)  # 定义目标函数值记录器,初始值为nan
     self.var_trace = (np.zeros(
         (self.MAXGEN, NVAR)) * np.nan)  # 定义变量记录器,记录决策变量值,初始值为nan
     self.forgetCount = 0  # “遗忘策略”计数器,用于记录连续出现最优个体不是可行个体的代数
     #===========================准备进化============================
     self.timeSlot = time.time()  # 开始计时
     if population.Chrom is None:
         population.initChrom(NIND)  # 初始化种群染色体矩阵(内含染色体解码,详见Population类的源码)
     population.ObjV, population.CV = self.problem.aimFuc(
         population.Phen, population.CV)  # 计算种群的目标函数值
     population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV,
                                   population.CV)  # 计算适应度
     self.evalsNum = population.sizes  # 记录评价次数
     #===========================开始进化============================
     self.currentGen = 0
     while self.terminated(population) == False:
         bestIdx = np.argmax(population.FitnV,
                             axis=0)  # 得到当代的最优个体的索引, 设置axis=0可使得返回一个向量
         studPop = population[np.tile(
             bestIdx, (NIND // 2))]  # 复制最优个体NIND//2份,组成一个“种马种群”
         restPop = population[np.where(
             np.array(range(NIND)) != bestIdx)[0]]  # 得到除去精英个体外其它个体组成的种群
         # 选择个体,以便后面与种马种群进行交配
         tempPop = restPop[ea.selecting(self.selFunc, restPop.FitnV,
                                        (NIND - studPop.sizes))]
         # 将种马种群与选择出来的个体进行合并
         population = studPop + tempPop
         # 进行进化操作
         population.Chrom = ea.recombin(self.recFunc, population.Chrom,
                                        self.pc)  # 重组
         population.Chrom = ea.mutate(self.mutFunc, population.Encoding,
                                      population.Chrom, population.Field,
                                      self.pm)  # 变异
         # 求进化后个体的目标函数值
         population.Phen = population.decoding()  # 染色体解码
         population.ObjV, population.CV = self.problem.aimFuc(
             population.Phen, population.CV)
         self.evalsNum += population.sizes  # 更新评价次数
         population.FitnV = ea.scaling(self.problem.maxormins *
                                       population.ObjV,
                                       population.CV)  # 计算适应度
     # 处理进化记录器
     delIdx = np.where(np.isnan(self.obj_trace))[0]
     self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
     self.var_trace = np.delete(self.var_trace, delIdx, 0)
     if self.obj_trace.shape[0] == 0:
         raise RuntimeError(
             'error: No feasible solution. (有效进化代数为0,没找到可行解。)')
     self.passTime += time.time() - self.timeSlot  # 更新用时记录
     # 绘图
     if self.drawing != 0:
         ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
     # 返回最后一代种群、进化记录器、变量记录器以及执行时间
     return [population, self.obj_trace, self.var_trace]
예제 #3
0
 def run(self):
     #==========================初始化配置===========================
     population = self.population
     NIND = population.sizes
     NVAR = self.problem.Dim  # 得到决策变量的个数
     self.obj_trace = (np.zeros(
         (self.MAXGEN, 2)) * np.nan)  # 定义目标函数值记录器,初始值为nan
     self.var_trace = (np.zeros(
         (self.MAXGEN, NVAR)) * np.nan)  # 定义变量记录器,记录决策变量值,初始值为nan
     self.forgetCount = 0  # “遗忘策略”计数器,用于记录连续出现最优个体不是可行个体的代数
     #===========================准备进化============================
     self.timeSlot = time.time()  # 开始计时
     if population.Chrom is None:
         population.initChrom(NIND)  # 初始化种群染色体矩阵(内含染色体解码,详见Population类的源码)
     population.ObjV, population.CV = self.problem.aimFuc(
         population.Phen, population.CV)  # 计算种群的目标函数值
     population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV,
                                   population.CV)  # 计算适应度
     self.evalsNum = population.sizes  # 记录评价次数
     #===========================开始进化============================
     self.currentGen = 0
     while self.terminated(population) == False:
         # 选择
         offspring = population[ea.selecting(self.selFunc, population.FitnV,
                                             NIND)]
         # 进行进化操作
         offspring.Chrom = ea.recombin(self.recFunc, offspring.Chrom,
                                       self.pc)  # 重组
         offspring.Chrom = ea.mutate(self.mutFunc, offspring.Encoding,
                                     offspring.Chrom, offspring.Field,
                                     self.pm)  # 变异
         # 求进化后个体的目标函数值
         offspring.Phen = offspring.decoding()  # 染色体解码
         offspring.ObjV, offspring.CV = self.problem.aimFuc(
             offspring.Phen, offspring.CV)
         self.evalsNum += offspring.sizes  # 更新评价次数
         population = population + offspring  # 父子合并
         population.FitnV = ea.scaling(self.problem.maxormins *
                                       population.ObjV,
                                       population.CV)  # 计算适应度
         # 得到新一代种群
         population = population[ea.selecting(self.selFunc,
                                              population.FitnV, NIND)]
     # 处理进化记录器
     delIdx = np.where(np.isnan(self.obj_trace))[0]
     self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
     self.var_trace = np.delete(self.var_trace, delIdx, 0)
     if self.obj_trace.shape[0] == 0:
         raise RuntimeError(
             'error: No feasible solution. (有效进化代数为0,没找到可行解。)')
     self.passTime += time.time() - self.timeSlot  # 更新用时记录
     # 绘图
     if self.drawing != 0:
         ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
     # 返回最后一代种群、进化记录器、变量记录器以及执行时间
     return [population, self.obj_trace, self.var_trace]
예제 #4
0
 def run(self):
     #==========================初始化配置===========================
     population = self.population
     NIND = population.sizes
     NVAR = self.problem.Dim  # 得到决策变量的个数
     self.obj_trace = (np.zeros(
         (self.MAXGEN, 2)) * np.nan)  # 定义目标函数值记录器,初始值为nan
     self.var_trace = (np.zeros(
         (self.MAXGEN, NVAR)) * np.nan)  # 定义变量记录器,记录决策变量值,初始值为nan
     self.forgetCount = 0  # “遗忘策略”计数器,用于记录连续出现最优个体不是可行个体的代数
     #===========================准备进化============================
     self.timeSlot = time.time()  # 开始计时
     if population.Chrom is None:
         population.initChrom(NIND)  # 初始化种群染色体矩阵(内含染色体解码,详见Population类的源码)
     population.ObjV, population.CV = self.problem.aimFuc(
         population.Phen, population.CV)  # 计算种群的目标函数值
     population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV,
                                   population.CV)  # 计算适应度
     self.evalsNum = population.sizes  # 记录评价次数
     #===========================开始进化============================
     self.currentGen = 0
     while self.terminated(population) == False:
         population.shuffle()  # 打乱个体顺序
         # 进行差分进化操作
         mutPop = population.copy()
         mutPop.Chrom = ea.mutate(self.mutFunc, mutPop.Encoding,
                                  mutPop.Chrom, mutPop.Field, self.F,
                                  1)  # 差分变异
         tempPop = population + mutPop  # 当代种群个体与变异个体进行合并(为的是后面用于重组)
         experimentPop = population.copy()  # 试验种群
         experimentPop.Chrom = ea.recombin(self.recFunc, tempPop.Chrom,
                                           self.pc, True)  # 重组
         # 求进化后个体的目标函数值
         experimentPop.Phen = experimentPop.decoding()  # 染色体解码
         experimentPop.ObjV, experimentPop.CV = self.problem.aimFuc(
             experimentPop.Phen, experimentPop.CV)
         self.evalsNum += experimentPop.sizes  # 更新评价次数
         tempPop = population + experimentPop  # 临时合并,以调用otos进行一对一生存者选择
         tempPop.FitnV = ea.scaling(self.problem.maxormins * tempPop.ObjV,
                                    tempPop.CV)  # 计算适应度
         population = tempPop[ea.selecting(
             'otos', tempPop.FitnV,
             NIND)]  # 采用One-to-One Survivor选择,产生新一代种群
     # 处理进化记录器
     delIdx = np.where(np.isnan(self.obj_trace))[0]
     self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
     self.var_trace = np.delete(self.var_trace, delIdx, 0)
     if self.obj_trace.shape[0] == 0:
         raise RuntimeError(
             'error: No feasible solution. (有效进化代数为0,没找到可行解。)')
     self.passTime += time.time() - self.timeSlot  # 更新用时记录
     # 绘图
     if self.drawing != 0:
         ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
     # 返回最后一代种群、进化记录器、变量记录器以及执行时间
     return [population, self.obj_trace, self.var_trace]
예제 #5
0
    def Plot_Save(self):
        self.best_gen = np.argmax(self.obj_trace[:, [1]])
        self.best_Objv = self.obj_trace[self.best_gen, 1]
        self.best_chrom_i = self.var_trace[self.best_gen]

        # pdb.set_trace()
        ea.trcplot(self.obj_trace, [['POP Mean Objv', 'Best Chrom i Objv']])

        with open(self.cfg.PARA.GACNN_params.save_bestdata_txt, 'a') as f:
            f.write('best_Objv=%.5f,best_chrom_i=%s,total_time=%.5f\n' %
                    (self.best_Objv, str(self.best_chrom_i), self.time))
예제 #6
0
def ea_select_model(config, log_name):
    #####################
    # set up parameters  #
    ######################
    if isinstance(config['ctx'], list):
        ctx = [mx.gpu(i) for i in config['ctx']]
    elif isinstance(config['ctx'], int):
        ctx = mx.gpu(config['ctx'])
    else:
        raise Exception("config_ctx error:" + str(config['ctx']))
    logger = Logger(log_name, config, False)

    #######################
    # init Env #
    #######################
    env = GNNEnv(config, ctx, logger)

    ##############
    #  training  #
    ##############
    problem = MyProblem(env, logger)
    Encoding = 'RI'
    NIND = 50
    Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,
                      problem.borders)
    population = ea.Population(Encoding, Field, NIND)
    myAlgorithm = ea.soea_DE_best_1_L_templet(problem, population)
    myAlgorithm.MAXGEN = 39
    myAlgorithm.logTras = 1
    myAlgorithm.verbose = True
    myAlgorithm.drawing = 1
    [NDSet, population] = myAlgorithm.run()
    NDSet.save()
    """==================================输出结果=============================="""
    print('用时:%f 秒' % myAlgorithm.passTime)
    print('评价次数:%d 次' % myAlgorithm.evalsNum)
    print('非支配个体数:%d 个' %
          NDSet.sizes) if NDSet.sizes != 0 else print('没有找到可行解!')
    if myAlgorithm.log is not None and NDSet.sizes != 0:
        print('eval', myAlgorithm.log['eval'][-1])
        print('f_opt', myAlgorithm.log['f_opt'][-1])
        print('f_max', myAlgorithm.log['f_max'][-1])
        print('f_avg', myAlgorithm.log['f_avg'][-1])
        print('f_min', myAlgorithm.log['f_min'][-1])
        print('f_std', myAlgorithm.log['f_std'][-1])
        """=========================进化过程指标追踪分析========================="""
        metricName = [['eval']]
        Metrics = np.array([
            myAlgorithm.log[metricName[i][0]] for i in range(len(metricName))
        ]).T
        # 绘制指标追踪分析图
        ea.trcplot(Metrics, labels=metricName, titles=metricName)
예제 #7
0
 def finishing(self, population): # 进化完成后调用的函数
     # 处理进化记录器
     delIdx = np.where(np.isnan(self.obj_trace))[0]
     self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
     self.var_trace = np.delete(self.var_trace, delIdx, 0)
     if self.obj_trace.shape[0] == 0:
         raise RuntimeError('error: No feasible solution. (有效进化代数为0,没找到可行解。)')
     self.passTime += time.time() - self.timeSlot # 更新用时记录
     # 绘图
     if self.drawing != 0:
         ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']], xlabels = [['Number of Generation']], ylabels = [['Value']], gridFlags = [[False]])
     # 返回最后一代种群、进化记录器、变量记录器以及执行时间
     return [population, self.obj_trace, self.var_trace]
예제 #8
0
    def draw(self, pop, EndFlag=False):
        """
        描述:
            该函数用于在进化过程中进行绘图。该函数在stat()以及finishing函数里面被调用。

        输入参数:
            pop     : class <Population> - 种群对象。
            
            EndFlag : bool - 表示是否是最后一次调用该函数。

        输出参数:
            无输出参数。

        """

        if not EndFlag:
            self.passTime += time.time() - self.timeSlot  # 更新用时记录,不计算画图的耗时
            # 绘制动画
            if self.drawing == 2:
                metric = np.array(self.trace['f_best']).reshape(-1, 1)
                self.ax = ea.soeaplot(metric,
                                      Label='Objective Value',
                                      saveFlag=False,
                                      ax=self.ax,
                                      gen=self.currentGen,
                                      gridFlag=False)  # 绘制动态图
            elif self.drawing == 3:
                self.ax = ea.varplot(pop.Phen,
                                     Label='decision variables',
                                     saveFlag=False,
                                     ax=self.ax,
                                     gen=self.currentGen,
                                     gridFlag=False)
            self.timeSlot = time.time()  # 更新时间戳
        else:
            # 绘制最终结果图
            if self.drawing != 0:
                metric = np.vstack([self.trace['f_avg'],
                                    self.trace['f_best']]).T
                ea.trcplot(metric, [['种群个体平均目标函数值', '种群最优个体目标函数值']],
                           xlabels=[['Number of Generation']],
                           ylabels=[['Value']],
                           gridFlags=[[False]])
예제 #9
0
 def output(self):
     if self.NDSet:
         print('用时:%s 秒' % (self.myAlgorithm.passTime))
         print('非支配个体数:%s 个' % (self.NDSet.sizes))
         print('单位时间找到帕累托前沿点个数:%s 个' %
               (int(self.NDSet.sizes // self.myAlgorithm.passTime)))
         PF = self.problem.getBest()
         if PF is not None and self.NDSet.sizes != 0:
             GD = ea.indicator.GD(self.NDSet.ObjV, PF)  #计算GD指标
             IGD = ea.indicator.IGD(self.NDSet.ObjV, PF)  # 计算IGD指标
             HV = ea.indicator.HV(self.NDSet.ObjV, PF)  #计算HV指标
             Spacing = ea.indicator.Spacing(self.NDSet.ObjV)  #计算Spacing指标
             print('GD:%f' % GD)
             print('IGD:%f' % IGD)
             print('HV:%f' % HV)
             print('Spacing:%f' % Spacing)
         """=====================进化过程指标追踪分析========================"""
         if PF is not None:
             metricName = [['IGD'], ['HV']]
             [NDSet_trace, Metrics] = ea.indicator.moea_tracking(
                 self.myAlgorithm.pop_trace, PF, metricName,
                 self.problem.maxormins)  # 绘制指标追踪分析图
             ea.trcplot(Metrics, labels=metricName, titles=metricName)
예제 #10
0
def sga_mps_real_templet(AIM_M,
                         AIM_F,
                         PUN_M,
                         PUN_F,
                         FieldDRs,
                         problem,
                         maxormin,
                         MAXGEN,
                         NIND,
                         SUBPOP,
                         GGAP,
                         selectStyle,
                         recombinStyle,
                         recopt,
                         pm,
                         drawing=1):
    """
sga_mps_real_templet.py - 基于多种群独立进化单目标编程模板(实值编码)

基于多种群独立进化单目标编程模板(实值编码),各种群独立将父子两代合并进行选择,采取精英保留机制

语法:
    该函数除了drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_mps_real_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:f = aimfuc(Phen)
            其中Phen是种群的表现型矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: f = punishing(Phen, FitnV)
            其中Phen是种群的表现型矩阵, FitnV为种群个体适应度列向量
    
    PUN_F : str - 罚函数名
    
    FieldDR : array - 实际值种群区域描述器
        [lb;		(float) 指明每个变量使用的下界
         ub]		(float) 指明每个变量使用的上界
         注:不需要考虑是否包含变量的边界值。在crtfld中已经将是否包含边界值进行了处理
         本函数生成的矩阵的元素值在FieldDR的[下界, 上界)之间
    
    problem : str - 表明是整数问题还是实数问题,'I'表示是整数问题,'R'表示是实数问题                 
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,本模板中该参数为无用参数,仅为了兼容同类的其他模板而设
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:aimfuc(Phen), 其中Phen表示种群的表现型矩阵
    2.本模板调用的罚函数形如: punishing(Phen, FitnV), 其中FitnV为用其他算法求得的适应度
      在罚函数定义中,必须将不满足约束条件的个体对应的适应度设为0,否则请修改模板使用

"""

    #==========================初始化配置==========================="""
    GGAP = 0.5  # 因为父子合并后选择,因此要将代沟设为0.5以维持种群规模
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    exIdx = np.array([])  # 存储非可行解的下标
    NVAR = FieldDRs[0].shape[1]  # 得到控制变量的个数
    # 定义全局进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    pop_trace[:, 0] = 0
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    """=========================开始遗传算法进化======================="""
    start_time = time.time()  # 开始计时
    # 对于各个网格分别进行进化,采用全局进化记录器记录最优值
    for index in range(len(FieldDRs)):
        FieldDR = FieldDRs[index]
        if problem == 'R':
            Chrom = ga.crtrp(NIND, FieldDR)  # 生成初始种群
        elif problem == 'I':
            Chrom = ga.crtip(NIND, FieldDR)
        repnum = 0  # 初始化重复个体数为0
        # 开始进化!!
        for gen in range(MAXGEN):
            # 进行遗传算子,生成子代
            SelCh = ga.recombin(recombinStyle, Chrom, recopt, SUBPOP)  # 重组
            if problem == 'R':
                SelCh = ga.mutbga(SelCh, FieldDR, pm)  # 变异
                if repnum > Chrom.shape[0] * 0.01:  # 当最优个体重复率高达1%时,进行一次高斯变异
                    SelCh = ga.mutgau(SelCh, FieldDR, pm)  # 高斯变异
            elif problem == 'I':
                SelCh = ga.mutint(SelCh, FieldDR, pm)
            Chrom = np.vstack([Chrom, SelCh])  # 父子合并
            ObjV = aimfuc(Chrom)  # 求后代的目标函数值
            FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)  # 适应度评价
            if PUN_F is not None:
                [FitnV, exIdx] = punishing(Chrom, FitnV)  # 调用罚函数
            repnum = len(
                np.where(ObjV[np.argmax(FitnV)] == ObjV)[0])  # 计算最优个体重复数
            # 记录进化过程
            bestIdx = np.argmax(FitnV)
            wrongSign = np.ones((FitnV.shape[0], 1))
            wrongSign[list(exIdx)] = 0  # 对非可行解作标记
            if FitnV[bestIdx] != 0:
                if (np.isnan(pop_trace[gen, 1])) or (
                    (maxormin == 1) &
                    (pop_trace[gen, 1] >= ObjV[bestIdx])) or (
                        (maxormin == -1) &
                        (pop_trace[gen, 1] <= ObjV[bestIdx])):
                    feasible = np.where(wrongSign != 0)[0]  # 排除非可行解
                    pop_trace[gen, 0] += np.sum(
                        ObjV[feasible]) / ObjV[feasible].shape[0] / len(
                            FieldDRs)  # 记录种群个体平均目标函数值
                    pop_trace[gen, 1] = ObjV[bestIdx]  # 记录当代目标函数的最优值
                    var_trace[gen, :] = Chrom[bestIdx, :]  # 记录当代最优的控制变量值
            Chrom = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
    end_time = time.time()  # 结束计时
    # 后处理进化记录器
    delIdx = np.where(np.isnan(pop_trace))[0]
    pop_trace = np.delete(pop_trace, delIdx, 0)
    var_trace = np.delete(var_trace, delIdx, 0)
    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.min(pop_trace[:, 1]))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.max(pop_trace[:, 1]))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    times = end_time - start_time
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #11
0
# 开始进化!!
start_time = time.time()  # 开始计时
for gen in range(MAXGEN):
    FitnV = ga.ranking(ObjV)  # 根据目标函数大小分配适应度值
    SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
    SelCh = ga.recombin(recombinStyle, SelCh, recopt, SUBPOP)  #交叉
    SelCh = ga.mutbin(SelCh, pm)  # 二进制种群变异
    Phen = ga.bs2rv(SelCh, FieldD)  # 对育种种群进行解码(二进制转十进制)
    ObjVSel = aimfuc(Phen)  # 求育种个体的目标函数值
    [Chrom, ObjV] = ga.reins(Chrom, SelCh, SUBPOP, 2, 1, ObjV,
                             ObjVSel)  # 重插入得到新一代种群
    # 记录
    best_ind = np.argmin(ObjV)  # 计算当代最优个体的序号
    pop_trace[gen, 0] = ObjV[best_ind]  # 记录当代种群最优个体目标函数值
    pop_trace[gen, 1] = np.sum(ObjV) / ObjV.shape[0]  # 记录当代种群的目标函数均值
    ind_trace[gen, :] = Chrom[best_ind, :]  # 记录当代种群最优个体的变量值
# 进化完成
end_time = time.time()  # 结束计时
"""============================绘图================================"""
ga.trcplot(pop_trace, [['最优个体目标函数值', '种群的目标函数均值']], ['demo_result'])
"""============================输出结果============================"""
best_gen = np.argmin(pop_trace[:, 0])  # 计算最优种群是在哪一代
print('最优的目标函数值为:', np.min(pop_trace[:, 0]))
print('最优的控制变量值为:')
# 最优个体记录器存储的是各代种群最优个体的染色体,此处需要解码得到对应的基因表现型
variables = ga.bs2rv(ind_trace, FieldD)  # 解码
for i in range(variables.shape[1]):
    print(variables[best_gen, i])
print('最优的一代是第', best_gen + 1, '代')
print('用时:', end_time - start_time, '秒')
예제 #12
0
def sga_new_code_templet(AIM_M,
                         AIM_F,
                         PUN_M,
                         PUN_F,
                         FieldD,
                         problem,
                         maxormin,
                         MAXGEN,
                         NIND,
                         SUBPOP,
                         GGAP,
                         selectStyle,
                         recombinStyle,
                         recopt,
                         pm,
                         drawing=1):
    """
sga_new_code_templet.py - 改进的单目标编程模板(二进制/格雷编码)

本模板实现改进单目标编程模板(二进制/格雷编码),将父子两代合并进行选择,增加了精英保留机制

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_new_code_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,传入该函数前通常由AIM_M = __import__('目标函数名')语句得到
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,传入该函数前通常由PUN_M = __import__('罚函数名')语句得到
    
    PUN_F : str - 罚函数名
    
    FieldD : array  - 二进制/格雷码种群区域描述器,描
        述种群每个个体的染色体长度和如何解码的矩阵,它有以下结构:
                    
        [lens;		(int) 每个控制变量编码后在染色体中所占的长度
         lb;		(float) 指明每个变量使用的下界
         ub;		(float) 指明每个变量使用的上界
         codes;	(0:binary     | 1:gray) 指明子串是怎么编码的,
                                          0为标准二进制编码,1为各类编码
         scales;  (0: rithmetic | 1:logarithmic) 指明每个子串是否使用对数或算术刻度, 
                                                 1为使用对数刻度,2为使用算术刻度
         lbin;		(0:excluded   | 1:included)
         ubin]		(0:excluded   | 1:included)
                
        lbin和ubin指明范围中是否包含每个边界。
        选择lbin=0或ubin=0,表示范围中不包含相应边界。
        选择lbin=1或ubin=1,表示范围中包含相应边界。
    
    problem : str - 表明是整数问题还是实数问题,'I'表示是整数问题,'R'表示是实数问题                 
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,本模板中该参数为无用参数,仅为了兼容同类的其他模板而设
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

"""
    """==========================初始化配置==========================="""
    GGAP = 0.5  # 因为父子合并后选择,因此要将代沟设为0.5以维持种群规模
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    NVAR = FieldD.shape[1]  # 得到控制变量的个数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    """=========================开始遗传算法进化======================="""
    Lind = np.sum(FieldD[0, :])  # 种群染色体长度
    Chrom = ga.crtbp(NIND, Lind)  # 生成初始种
    start_time = time.time()  # 开始计时
    # 开始进化!!
    for gen in range(MAXGEN):
        # 进行遗传算子产生子代
        SelCh = ga.recombin(recombinStyle, Chrom, recopt, SUBPOP)  # 重组
        SelCh = ga.mutbin(SelCh, pm)  # 变异
        Chrom = np.vstack([Chrom, SelCh])  # 父子合并
        # 计算种群适应度
        if problem == 'R':
            variable = ga.bs2rv(Chrom, FieldD)  # 解码
        elif problem == 'I':
            if np.any(FieldD >= sys.maxsize):
                variable = ga.bs2int(Chrom, FieldD).astype('object')  # 解码
            else:
                variable = ga.bs2int(Chrom, FieldD).astype('int64')
        ObjV = aimfuc(variable)  # 求后代的目标函数值
        pop_trace[gen, 0] = np.sum(ObjV) // ObjV.shape[0]  # 记录种群个体平均目标函数值
        if maxormin == 1:
            pop_trace[gen, 1] = np.min(ObjV)  # 记录当代目标函数的最优值
            var_trace[gen, :] = variable[np.argmin(ObjV), :]  # 记录当代最优的控制变量值
        elif maxormin == -1:
            pop_trace[gen, 1] = np.max(ObjV)
            var_trace[gen, :] = variable[np.argmax(ObjV), :]  # 记录当代最优的控制变量值
        # 最后对合并的种群进行适应度评价并选出一半个体留到下一代
        FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(Chrom, FitnV)  # 调用罚函数
        Chrom = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
    end_time = time.time()  # 结束计时

    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:' + str(np.min(pop_trace[:, 1])))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:' + str(np.max(pop_trace[:, 1])))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第' + str(best_gen + 1) + '代')
    times = end_time - start_time
    print('时间已过' + str(times) + '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #13
0
def sga_permut_templet(AIM_M,
                       AIM_F,
                       PUN_M,
                       PUN_F,
                       NVAR,
                       VarLen,
                       maxormin,
                       MAXGEN,
                       NIND,
                       SUBPOP,
                       GGAP,
                       selectStyle,
                       recombinStyle,
                       recopt,
                       pm,
                       distribute,
                       drawing=1):
    """
sga_permut_templet.py - 单目标编程模板(排列编码)

排列编码即每条染色体的基因都是无重复正整数的编码方式。

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_permut_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:[f,LegV] = aimfuc(Phen,LegV)
            其中Phen是种群的表现型矩阵, LegV为种群的可行性列向量,f为种群的目标函数值矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: newFitnV = punishing(LegV, FitnV)
            其中LegV为种群的可行性列向量, FitnV为种群个体适应度列向量
            一般在罚函数中对LegV为0的个体进行适应度惩罚,返回修改后的适应度列向量newFitnV
    
    PUN_F : str - 罚函数名
    
    NVAR : int - 变量个数,排列编码的染色体长度等于变量个数
    
    VarLen : int - 排列集合的大小
                   例如VarLen = 5表示是从1,2,3,4,5中抽取若干个数排列组成染色体
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,表示子代与父代染色体及性状不相同的概率
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    distribute : bool - 是否增强种群的分布性(可能会造成收敛慢)
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:[ObjV,LegV] = aimfuc(Phen,LegV), 
      其中Phen表示种群的表现型矩阵, LegV为种群的可行性列向量(详见Geatpy数据结构)
    2.本模板调用的罚函数形如: newFitnV = punishing(LegV, FitnV), 
      其中FitnV为用其他算法求得的适应度
    若不符合上述规范,则请修改算法模板或自定义新算法模板
    3.关于'maxormin': geatpy的内核函数全是遵循“最小化目标”的约定的,即目标函数值越小越好。
      当需要优化最大化的目标时,需要设置'maxormin'为-1。
      本算法模板是正确使用'maxormin'的典型范例,其具体用法如下:
      当调用的函数传入参数包含与“目标函数值矩阵”有关的参数(如ObjV,ObjVSel,NDSetObjV等)时,
      查看该函数的参考资料(可用'help'命令查看,也可到官网上查看相应的教程),
      里面若要求传入前对参数乘上'maxormin',则需要乘上。
      里面若要求对返回参数乘上'maxormin'进行还原,
      则调用函数返回得到的相应参数需要乘上'maxormin'进行还原,否则其正负号就会被改变。

"""
    """==========================初始化配置==========================="""
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    ax = None  # 存储上一帧图形
    """=========================开始遗传算法进化======================="""
    #生成初始种群
    Chrom = ga.crtpp(NIND, NVAR, VarLen)
    LegV = np.ones((NIND, 1))  # 初始化种群的可行性列向量
    [ObjV, LegV] = aimfuc(Chrom, LegV)  # 求种群的目标函数值
    gen = 0
    badCounter = 0  # 用于记录在“遗忘策略下”被忽略的代数
    # 开始进化!!
    start_time = time.time()  # 开始计时
    while gen < MAXGEN:
        if badCounter >= 10 * MAXGEN:  # 若多花了10倍的迭代次数仍没有可行解出现,则跳出
            break
        FitnV = ga.ranking(maxormin * ObjV, LegV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(LegV, FitnV)  # 调用罚函数
        # 记录进化过程
        bestIdx = np.argmax(FitnV)  # 获取最优个体的下标
        if LegV[bestIdx] != 0:
            feasible = np.where(LegV != 0)[0]  # 排除非可行解
            pop_trace[gen, 0] = np.sum(
                ObjV[feasible]) / ObjV[feasible].shape[0]  # 记录种群个体平均目标函数值
            pop_trace[gen, 1] = ObjV[bestIdx]  # 记录当代目标函数的最优值
            var_trace[gen, :] = Chrom[bestIdx, :]  # 记录当代最优的控制变量值
            # 绘制动态图
            if drawing == 2:
                ax = ga.sgaplot(pop_trace[:, [1]], '种群最优个体目标函数值', False, ax,
                                gen)
            badCounter = 0  # badCounter计数器清零
        else:
            gen -= 1  # 忽略这一代(遗忘策略)
            badCounter += 1
        # 进行遗传算子
        SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
        SelCh = ga.recombin(recombinStyle, SelCh, recopt, SUBPOP)  # 对选择的个体进行重组
        SelCh = ga.mutpp(SelCh, VarLen, pm)  # 排列编码种群变异
        LegVSel = np.ones((SelCh.shape[0], 1))  # 初始化育种种群的可行性列向量
        [ObjVSel, LegVSel] = aimfuc(SelCh, LegVSel)  # 求育种种群的目标函数值
        FitnVSel = ga.ranking(maxormin * ObjVSel, LegVSel, None,
                              SUBPOP)  # 计算育种种群的适应度
        if PUN_F is not None:
            FitnVSel = punishing(LegVSel, FitnVSel)  # 调用罚函数
        # 重插入
        [Chrom, ObjV, LegV] = ga.reins(Chrom, SelCh, SUBPOP, 1, 1, FitnV,
                                       FitnVSel, ObjV, ObjVSel, LegV, LegVSel)
        gen += 1
    end_time = time.time()  # 结束计时
    times = end_time - start_time
    # 后处理进化记录器
    delIdx = np.where(np.isnan(pop_trace))[0]
    pop_trace = np.delete(pop_trace, delIdx, 0)
    var_trace = np.delete(var_trace, delIdx, 0)
    if pop_trace.shape[0] == 0:
        raise RuntimeError('error: no feasible solution. (有效进化代数为0,没找到可行解。)')
    # 绘图
    if drawing != 0:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.min(pop_trace[:, 1])
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.max(pop_trace[:, 1])
    print('最优的目标函数值为:%f' % (best_ObjV))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('有效进化代数:%d' % (pop_trace.shape[0]))
    print('最优的一代是第 %d 代' % (best_gen + 1))
    print('时间已过 %f 秒' % (times))
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #14
0
def sga_new_permut_templet(AIM_M,
                           AIM_F,
                           PUN_M,
                           PUN_F,
                           NVAR,
                           VarLen,
                           maxormin,
                           MAXGEN,
                           NIND,
                           SUBPOP,
                           GGAP,
                           selectStyle,
                           recombinStyle,
                           recopt,
                           pm,
                           drawing=1):
    """
sga_new_permut_templet.py - 改进的单目标编程模板(排列编码)

本模板实现改进单目标编程模板(排列编码),将父子两代合并进行选择,增加了精英保留机制

排列编码即每条染色体的基因都是无重复正整数的编码方式。

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_new_permut_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:f = aimfuc(Phen)
            其中Phen是种群的表现型矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: f = punishing(Phen, FitnV)
            其中Phen是种群的表现型矩阵, FitnV为种群个体适应度列向量
    
    PUN_F : str - 罚函数名
    
    NVAR : int - 变量个数,排列编码的染色体长度等于变量个数
    
    VarLen : int - 排列集合的大小
                   例如VarLen = 5表示是从1,2,3,4,5中抽取若干个数排列组成染色体
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,本模板中该参数为无用参数,仅为了兼容同类的其他模板而设
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

"""
    """==========================初始化配置==========================="""
    GGAP = 0.5  # 因为父子合并后选择,因此要将代沟设为0.5以维持种群规模
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    """=========================开始遗传算法进化======================="""
    Chrom = ga.crtpp(NIND, NVAR, VarLen)  #生成初始种群
    start_time = time.time()  # 开始计时
    # 开始进化!!
    for gen in range(MAXGEN):
        # 进行遗传算子,生成子代
        SelCh = ga.recombin(recombinStyle, Chrom, recopt, SUBPOP)  # 重组
        SelCh = ga.mutpp(SelCh, VarLen, pm)  # 排列编码种群变异
        Chrom = np.vstack([Chrom, SelCh])  # 父子合并
        ObjV = aimfuc(Chrom)  # 求后代的目标函数值
        pop_trace[gen, 0] = np.sum(ObjV) / ObjV.shape[0]  # 记录种群个体平均目标函数值
        if maxormin == 1:
            pop_trace[gen, 1] = np.min(ObjV)  # 记录当代目标函数的最优值
            var_trace[gen, :] = Chrom[np.argmin(ObjV), :]  # 记录当代最优的控制变量值
        elif maxormin == -1:
            pop_trace[gen, 1] = np.max(ObjV)
            var_trace[gen, :] = Chrom[np.argmax(ObjV), :]  # 记录当代最优的控制变量值
        # 最后对合并的种群进行适应度评价并选出一半个体留到下一代
        FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(Chrom, FitnV)  # 调用罚函数
        Chrom = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择

    end_time = time.time()  # 结束计时

    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.min(pop_trace[:, 1]))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.max(pop_trace[:, 1]))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    times = end_time - start_time
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #15
0
def sga_code_templet(AIM_M,
                     AIM_F,
                     PUN_M,
                     PUN_F,
                     FieldD,
                     problem,
                     maxormin,
                     MAXGEN,
                     NIND,
                     SUBPOP,
                     GGAP,
                     selectStyle,
                     recombinStyle,
                     recopt,
                     pm,
                     distribute,
                     drawing=1):
    """
sga_code_templet.py - 单目标编程模板(二进制/格雷编码)

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_code_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:[f,LegV] = aimfuc(Phen,LegV)
            其中Phen是种群的表现型矩阵, LegV为种群的可行性列向量,f为种群的目标函数值矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: newFitnV = punishing(LegV, FitnV)
            其中LegV为种群的可行性列向量, FitnV为种群个体适应度列向量
            一般在罚函数中对LegV为0的个体进行适应度惩罚,返回修改后的适应度列向量newFitnV
    
    PUN_F : str - 罚函数名
    
    FieldD : array  - 二进制/格雷码种群区域描述器,
        描述种群每个个体的染色体长度和如何解码的矩阵,它有以下结构:
                    
        [lens;		(int) 每个控制变量编码后在染色体中所占的长度
         lb;		(float) 指明每个变量使用的下界
         ub;		(float) 指明每个变量使用的上界
         codes;	(0:binary     | 1:gray) 指明子串是怎么编码的,
                                          0为标准二进制编码,1为各类编码
         scales;  (0: rithmetic | 1:logarithmic) 指明每个子串是否使用对数或算术刻度, 
                                                 1为使用对数刻度,2为使用算术刻度
         lbin;		(0:excluded   | 1:included)
         ubin]		(0:excluded   | 1:included)
                
        lbin和ubin指明范围中是否包含每个边界。
        选择lbin=0或ubin=0,表示范围中不包含相应边界。
        选择lbin=1或ubin=1,表示范围中包含相应边界。
    
    problem : str - 表明是整数问题还是实数问题,'I'表示是整数问题,'R'表示是实数问题                 
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,表示子代与父代染色体及性状不相同的概率
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    distribute : bool - 是否增强种群的分布性(可能会造成收敛慢)
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:[ObjV,LegV] = aimfuc(Phen,LegV), 
      其中Phen表示种群的表现型矩阵, LegV为种群的可行性列向量(详见Geatpy数据结构)
    2.本模板调用的罚函数形如: newFitnV = punishing(LegV, FitnV), 
      其中FitnV为用其他算法求得的适应度
    若不符合上述规范,则请修改算法模板或自定义新算法模板
    3.关于'maxormin': geatpy的内核函数全是遵循“最小化目标”的约定的,即目标函数值越小越好。
      当需要优化最大化的目标时,需要设置'maxormin'为-1。
      本算法模板是正确使用'maxormin'的典型范例,其具体用法如下:
      当调用的函数传入参数包含与“目标函数值矩阵”有关的参数(如ObjV,ObjVSel,NDSetObjV等)时,
      查看该函数的参考资料(可用'help'命令查看,也可到官网上查看相应的教程),
      里面若要求传入前对参数乘上'maxormin',则需要乘上。
      里面若要求对返回参数乘上'maxormin'进行还原,
      则调用函数返回得到的相应参数需要乘上'maxormin'进行还原,否则其正负号就会被改变。

"""

    #==========================初始化配置==========================="""
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    NVAR = FieldD.shape[1]  # 得到控制变量的个数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    ax = None  # 存储上一帧图形
    """=========================开始遗传算法进化======================="""
    Lind = np.sum(FieldD[0, :])  # 种群染色体长度
    Chrom = ga.crtbp(NIND, Lind)  # 生成初始种群
    if problem == 'R':
        variable = ga.bs2rv(Chrom, FieldD)  # 解码
    elif problem == 'I':
        if np.any(FieldD >= sys.maxsize):
            variable = ga.bs2int(Chrom, FieldD).astype('object')  # 解码
        else:
            variable = ga.bs2int(Chrom, FieldD).astype('int64')  # 解码
    LegV = np.ones((NIND, 1))  # 生成可行性列向量,元素为1表示对应个体是可行解,0表示非可行解
    [ObjV, LegV] = aimfuc(variable, LegV)  # 求种群的目标函数值
    gen = 0
    badCounter = 0  # 用于记录在“遗忘策略下”被忽略的代数
    # 开始进化!!
    start_time = time.time()  # 开始计时
    while gen < MAXGEN:
        if badCounter >= 10 * MAXGEN:  # 若多花了10倍的迭代次数仍没有可行解出现,则跳出
            break
        FitnV = ga.ranking(maxormin * ObjV, LegV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(LegV, FitnV)  # 调用罚函数
        # 记录进化过程
        bestIdx = np.argmax(FitnV)  # 获取最优个体的下标
        if LegV[bestIdx] != 0:
            feasible = np.where(LegV != 0)[0]  # 排除非可行解
            pop_trace[gen, 0] = np.sum(
                ObjV[feasible]) / ObjV[feasible].shape[0]  # 记录种群个体平均目标函数值
            pop_trace[gen, 1] = ObjV[bestIdx]  # 记录当代目标函数的最优值
            var_trace[gen, :] = variable[bestIdx, :]  # 记录当代最优的控制变量值
            # 绘制动态图
            if drawing == 2:
                ax = ga.sgaplot(pop_trace[:, [1]], '种群最优个体目标函数值', False, ax,
                                gen)
            badCounter = 0  # badCounter计数器清零
        else:
            gen -= 1  # 忽略这一代(遗忘策略)
            badCounter += 1
        if distribute == True:  # 若要增强种群的分布性(可能会造成收敛慢)
            idx = np.argsort(ObjV[:, 0], 0)
            dis = np.diff(ObjV[idx, 0]) / (np.max(ObjV[idx, 0]) - np.min(
                ObjV[idx, 0]) + 1)  # 差分计算距离的修正偏移量
            dis = np.hstack([dis, dis[-1]])
            dis = dis + np.min(dis)  # 修正偏移量+最小量=修正绝对量
            FitnV[idx, 0] *= np.exp(dis)  # 根据相邻距离修改适应度,突出相邻距离大的个体,以增加种群的多样性
        # 进行遗传算子
        SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
        SelCh = ga.recombin(recombinStyle, SelCh, recopt, SUBPOP)  # 对所选个体进行重组
        SelCh = ga.mutbin(SelCh, pm)  # 变异
        # 计算种群适应度
        if problem == 'R':
            variable = ga.bs2rv(SelCh, FieldD)  # 解码
        elif problem == 'I':
            if np.any(FieldD >= sys.maxsize):
                variable = ga.bs2int(SelCh, FieldD).astype('object')  # 解码
            else:
                variable = ga.bs2int(SelCh, FieldD).astype('int64')
        LegVSel = np.ones((SelCh.shape[0], 1))  # 初始化育种种群的可行性列向量
        [ObjVSel, LegVSel] = aimfuc(variable, LegVSel)  # 求后代的目标函数值
        FitnVSel = ga.ranking(maxormin * ObjVSel, LegVSel, None,
                              SUBPOP)  # 计算育种种群的适应度
        if PUN_F is not None:
            FitnVSel = punishing(LegVSel, FitnVSel)  # 调用罚函数
        # 重插入
        [Chrom, ObjV, LegV] = ga.reins(Chrom, SelCh, SUBPOP, 1, 1, FitnV,
                                       FitnVSel, ObjV, ObjVSel, LegV, LegVSel)
        # 计算新一代种群的控制变量解码值
        if problem == 'R':
            variable = ga.bs2rv(Chrom, FieldD)  # 解码
        elif problem == 'I':
            if np.any(FieldD >= sys.maxsize):
                variable = ga.bs2int(Chrom, FieldD).astype('object')  # 解码
            else:
                variable = ga.bs2int(Chrom, FieldD).astype('int64')
        gen += 1
    end_time = time.time()  # 结束计时
    times = end_time - start_time
    # 后处理进化记录器
    delIdx = np.where(np.isnan(pop_trace))[0]
    pop_trace = np.delete(pop_trace, delIdx, 0)
    var_trace = np.delete(var_trace, delIdx, 0)
    if pop_trace.shape[0] == 0:
        raise RuntimeError('error: no feasible solution. (有效进化代数为0,没找到可行解。)')
    # 绘图
    if drawing != 0:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.min(pop_trace[:, 1])
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.max(pop_trace[:, 1])
    print('最优的目标函数值为:%s' % (best_ObjV))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('有效进化代数:%s' % (pop_trace.shape[0]))
    print('最优的一代是第 %s 代' % (best_gen + 1))
    print('时间已过 %s 秒' % (times))
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #16
0
b2 = [0, 1]  # 自变量的边界
ranges = np.vstack([x1, x2]).T  # 生成自变量的范围矩阵
borders = np.vstack([b1, b2]).T  # 生成自变量的边界矩阵
"""========================遗传算法参数设置========================="""
NIND = 50  # 种群规模
MAXGEN = 500  # 最大遗传代数
GGAP = 0.8  # 代沟:子代与父代的重复率为(1-GGAP)
selectStyle = 'rws'  # 遗传算法的选择方式设为"rws"——轮盘赌选择
recombinStyle = 'xovdp'  # 遗传算法的重组方式,设为两点交叉
recopt = 0.9  # 交叉概率
pm = 0.01  # 变异概率
SUBPOP = 1  # 设置种群数为1
maxormin = 1  # 设置标记表明这是最小化目标
"""=======================调用编程模板进行种群进化==================="""
# 调用编程模板进行种群进化,得到种群进化和变量的追踪器以及运行时间
[pop_trace, var_trace,
 times] = mintemp1(AIM_M, 'aimfuc', PUN_M, 'punishing', ranges, borders,
                   MAXGEN, NIND, SUBPOP, GGAP, selectStyle, recombinStyle,
                   recopt, pm, maxormin)
"""=========================绘图及输出结果========================="""
# 传入pop_trace进行绘图
gea.trcplot(pop_trace, [['各代种群最优目标函数值'], ['各代种群个体平均适应度值', '各代种群最优个体适应度值']],
            ['demo_result1', 'demo_result2'])
# 输出结果
best_gen = np.argmin(pop_trace[:, 0])  # 记录最优种群是在哪一代
print('最优的目标函数值为:', np.min(pop_trace[:, 0]))
print('最优的控制变量值为:')
for i in range(var_trace.shape[1]):
    print(var_trace[best_gen, i])
print('最优的一代是第', best_gen + 1, '代')
print('用时:', times, '秒')
예제 #17
0
def sga_permut_templet(AIM_M, AIM_F, PUN_M, PUN_F, NVAR, VarLen, maxormin, MAXGEN, NIND, SUBPOP, GGAP, selectStyle, recombinStyle, recopt, pm, drawing = 1):
    
    """
sga_permut_templet.py - 单目标编程模板(排列编码)

排列编码即每条染色体的基因都是无重复正整数的编码方式。

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_permut_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:f = aimfuc(Phen)
            其中Phen是种群的表现型矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: f = punishing(Phen, FitnV)
            其中Phen是种群的表现型矩阵, FitnV为种群个体适应度列向量
    
    PUN_F : str - 罚函数名
    
    NVAR : int - 变量个数,排列编码的染色体长度等于变量个数
    
    VarLen : int - 排列集合的大小
                   例如VarLen = 5表示是从1,2,3,4,5中抽取若干个数排列组成染色体
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,表示子代与父代染色体及性状不相同的概率
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:aimfuc(Phen), 其中Phen表示种群的表现型矩阵
    2.本模板调用的罚函数形如: punishing(Phen, FitnV), 其中FitnV为用其他算法求得的适应度
      在罚函数定义中,必须将不满足约束条件的个体对应的适应度设为0,否则请修改模板使用

"""
    """==========================初始化配置==========================="""
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F) # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F) # 获得罚函数
    exIdx = np.array([]) # 存储非可行解的下标
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN ,2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN ,NVAR)) * np.nan) 
    """=========================开始遗传算法进化======================="""
    #生成初始种群
    Chrom = ga.crtpp(NIND, NVAR, VarLen)
    ObjV = aimfuc(Chrom) # 求种群的目标函数值
    
    start_time = time.time() # 开始计时
    # 开始进化!!
    for gen in range(MAXGEN):
        FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)
        if PUN_F is not None:
            [FitnV, exIdx] = punishing(Chrom, FitnV) # 调用罚函数
        # 记录进化过程
        bestIdx = np.argmax(FitnV) # 获取最优个体的下标
        wrongSign = np.ones((FitnV.shape[0], 1))
        wrongSign[list(exIdx)] = 0 # 对非可行解作标记
        if wrongSign[bestIdx] != 0:
            feasible = np.where(wrongSign != 0)[0] # 排除非可行解
            pop_trace[gen,0] = np.sum(ObjV[feasible]) / ObjV[feasible].shape[0] # 记录种群个体平均目标函数值
            pop_trace[gen,1] = ObjV[bestIdx] # 记录当代目标函数的最优值
            var_trace[gen,:] = Chrom[bestIdx, :] # 记录当代最优的控制变量值
        # 进行遗传算子
        SelCh=ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP) # 选择
        SelCh=ga.recombin(recombinStyle, Chrom, recopt, SUBPOP) # 重组
        SelCh=ga.mutpp(SelCh, VarLen, pm) # 排列编码种群变异
        ObjVSel = aimfuc(SelCh) # 求后代的目标函数值
        # 重插入
        [Chrom, ObjV]=ga.reins(Chrom, SelCh, SUBPOP, 2, 1, ObjV, ObjVSel)
    end_time = time.time() # 结束计时
    # 后处理进化记录器
    delIdx = np.where(np.isnan(pop_trace))[0]
    pop_trace = np.delete(pop_trace, delIdx, 0)
    var_trace = np.delete(var_trace, delIdx, 0)
    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1]) # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.min(pop_trace[:, 1]))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1]) # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.max(pop_trace[:, 1]))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    times = end_time - start_time
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #18
0
myAlgorithm.drawing = 1 # 设置绘图方式(0:不绘图;1:绘制结果图;2:绘制目标空间过程动画;3:绘制决策空间过程动画)
"""===========================调用算法模板进行种群进化=========================
调用run执行算法模板,得到帕累托最优解集NDSet。NDSet是一个种群类Population的对象。
NDSet.ObjV为最优解个体的目标函数值;NDSet.Phen为对应的决策变量值。
详见Population.py中关于种群类的定义。
"""
NDSet = myAlgorithm.run() # 执行算法模板,得到非支配种群
NDSet.save()              # 把结果保存到文件中
# 输出
print('用时:%f 秒'%(myAlgorithm.passTime))
print('评价次数:%d 次'%(myAlgorithm.evalsNum))
print('非支配个体数:%d 个'%(NDSet.sizes))
print('单位时间找到帕累托前沿点个数:%d 个'%(int(NDSet.sizes // myAlgorithm.passTime)))
# 计算指标
PF = problem.getBest() # 获取真实前沿,详见Problem.py中关于Problem类的定义
if PF is not None and NDSet.sizes != 0:
    GD = ea.indicator.GD(NDSet.ObjV, PF)       # 计算GD指标
    IGD = ea.indicator.IGD(NDSet.ObjV, PF)     # 计算IGD指标
    HV = ea.indicator.HV(NDSet.ObjV, PF)       # 计算HV指标
    Spacing = ea.indicator.Spacing(NDSet.ObjV) # 计算Spacing指标
    print('GD',GD)
    print('IGD',IGD)
    print('HV', HV)
    print('Spacing', Spacing)
"""=============================进化过程指标追踪分析============================"""
if PF is not None:
    metricName = [['IGD'], ['HV']]
    [NDSet_trace, Metrics] = ea.indicator.moea_tracking(myAlgorithm.pop_trace, PF, metricName, problem.maxormins)
    # 绘制指标追踪分析图
    ea.trcplot(Metrics, labels = metricName, titles = metricName)
예제 #19
0
 def run(self):
     #==========================初始化配置===========================
     population = self.population
     NIND = population.sizes
     NVAR = self.problem.Dim  # 得到决策变量的个数
     self.obj_trace = (np.zeros(
         (self.MAXGEN, 2)) * np.nan)  # 定义目标函数值记录器,初始值为nan
     self.var_trace = (np.zeros(
         (self.MAXGEN, NVAR)) * np.nan)  # 定义变量记录器,记录决策变量值,初始值为nan
     self.forgetCount = 0  # “遗忘策略”计数器,用于记录连续出现最优个体不是可行个体的代数
     #===========================准备进化============================
     self.timeSlot = time.time()  # 开始计时
     if population.Chrom is None:
         population.initChrom(NIND)  # 初始化种群染色体矩阵(内含染色体解码,详见Population类的源码)
     population.ObjV, population.CV = self.problem.aimFuc(
         population.Phen, population.CV)  # 计算种群的目标函数值
     population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV,
                                   population.CV)  # 计算适应度
     self.evalsNum = population.sizes  # 记录评价次数
     Sigma = 0.5 * (population.Field[1, :] -
                    population.Field[0, :]) / 3  # 初始化高斯变异的Sigma
     #===========================开始进化============================
     self.currentGen = 0
     while self.terminated(population) == False:
         # 进行进化操作
         experimentPop = population.copy()  # 存储试验种群
         experimentPop.Chrom = ea.mutate('mutgau', experimentPop.Encoding,
                                         experimentPop.Chrom,
                                         experimentPop.Field,
                                         experimentPop.Lind,
                                         Sigma)  # 变异(这里变异概率设为染色体长度)
         # 求进化后个体的目标函数值
         experimentPop.Phen = experimentPop.decoding()  # 染色体解码
         experimentPop.ObjV, experimentPop.CV = self.problem.aimFuc(
             experimentPop.Phen, experimentPop.CV)
         self.evalsNum += population.sizes  # 更新评价次数
         tempPop = population + experimentPop  # 临时合并,以调用otos进行一对一生存者选择
         tempPop.FitnV = ea.scaling(self.problem.maxormins * tempPop.ObjV,
                                    tempPop.CV)  # 计算适应度
         chooseIdx = ea.selecting('otos', tempPop.FitnV,
                                  NIND)  # 采用One-to-One Survivor选择
         population = tempPop[chooseIdx]  # 产生新一代种群
         # 利用1/5规则调整变异压缩概率(实质上是通过变异压缩概率来调整高斯变异的标准差,详见mutgau帮助文档)
         successfulRate = len(np.where(chooseIdx >= NIND)[0]) / (2 * NIND)
         if successfulRate < 1 / 5:
             Sigma *= 0.817
         elif successfulRate > 1 / 5:
             Sigma /= 0.817
     # 处理进化记录器
     delIdx = np.where(np.isnan(self.obj_trace))[0]
     self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
     self.var_trace = np.delete(self.var_trace, delIdx, 0)
     if self.obj_trace.shape[0] == 0:
         raise RuntimeError(
             'error: No feasible solution. (有效进化代数为0,没找到可行解。)')
     self.passTime += time.time() - self.timeSlot  # 更新用时记录
     # 绘图
     if self.drawing != 0:
         ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
     # 返回最后一代种群、进化记录器、变量记录器以及执行时间
     return [population, self.obj_trace, self.var_trace]
예제 #20
0
def sga_new_permut_templet(AIM_M,
                           AIM_F,
                           PUN_M,
                           PUN_F,
                           NVAR,
                           VarLen,
                           maxormin,
                           MAXGEN,
                           NIND,
                           SUBPOP,
                           GGAP,
                           selectStyle,
                           recombinStyle,
                           recopt,
                           pm,
                           distribute,
                           drawing=1):
    """
sga_new_permut_templet.py - 改进的单目标编程模板(排列编码)

本模板实现改进单目标编程模板(排列编码),将父子两代合并进行选择,增加了精英保留机制

排列编码即每条染色体的基因都是无重复正整数的编码方式。

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_new_permut_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:[f,LegV] = aimfuc(Phen,LegV)
            其中Phen是种群的表现型矩阵, LegV为种群的可行性列向量,f为种群的目标函数值矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: newFitnV = punishing(LegV, FitnV)
            其中LegV为种群的可行性列向量, FitnV为种群个体适应度列向量
            一般在罚函数中对LegV为0的个体进行适应度惩罚,返回修改后的适应度列向量newFitnV
    
    PUN_F : str - 罚函数名
    
    NVAR : int - 变量个数,排列编码的染色体长度等于变量个数
    
    VarLen : int - 排列集合的大小
                   例如VarLen = 5表示是从1,2,3,4,5中抽取若干个数排列组成染色体
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,本模板中该参数为无用参数,仅为了兼容同类的其他模板而设
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    distribute : bool - 是否增强种群的分布性(可能会造成收敛慢)
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:[ObjV,LegV] = aimfuc(Phen,LegV), 
      其中Phen表示种群的表现型矩阵, LegV为种群的可行性列向量(详见Geatpy数据结构)
    2.本模板调用的罚函数形如: newFitnV = punishing(LegV, FitnV), 
      其中FitnV为用其他算法求得的适应度
    若不符合上述规范,则请修改算法模板或自定义新算法模板
    3.关于'maxormin': geatpy的内核函数全是遵循“最小化目标”的约定的,即目标函数值越小越好。
      当需要优化最大化的目标时,需要设置'maxormin'为-1。
      本算法模板是正确使用'maxormin'的典型范例,其具体用法如下:
      当调用的函数传入参数包含与“目标函数值矩阵”有关的参数(如ObjV,ObjVSel,NDSetObjV等)时,
      查看该函数的参考资料(可用'help'命令查看,也可到官网上查看相应的教程),
      里面若要求传入前对参数乘上'maxormin',则需要乘上。
      里面若要求对返回参数乘上'maxormin'进行还原,
      则调用函数返回得到的相应参数需要乘上'maxormin'进行还原,否则其正负号就会被改变。

"""
    """==========================初始化配置==========================="""
    GGAP = 0.5  # 因为父子合并后选择,因此要将代沟设为0.5以维持种群规模
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    ax = None  # 存储上一帧图形
    """=========================开始遗传算法进化======================="""
    Chrom = ga.crtpp(NIND, NVAR, VarLen)  #生成初始种群
    LegV = np.ones((NIND, 1))  # 生成可行性列向量,元素为1表示对应个体是可行解,0表示非可行解
    [ObjV, LegV] = aimfuc(Chrom, LegV)  # 求初代的目标函数值
    gen = 0
    badCounter = 0  # 用于记录在“遗忘策略下”被忽略的代数
    # 开始进化!!
    start_time = time.time()  # 开始计时
    while gen < MAXGEN:
        if badCounter >= 10 * MAXGEN:  # 若多花了10倍的迭代次数仍没有可行解出现,则跳出
            break
        # 进行遗传算子,生成子代
        SelCh = ga.recombin(recombinStyle, Chrom, recopt, SUBPOP)  # 重组
        SelCh = ga.mutpp(SelCh, VarLen, pm)  # 排列编码种群变异
        LegVSel = np.ones((SelCh.shape[0], 1))  # 初始化育种种群的可行性列向量
        [ObjVSel, LegVSel] = aimfuc(SelCh, LegVSel)  # 求后代的目标函数值
        # 父子合并
        Chrom = np.vstack([Chrom, SelCh])
        ObjV = np.vstack([ObjV, ObjVSel])
        LegV = np.vstack([LegV, LegVSel])
        # 对合并的种群进行适应度评价
        FitnV = ga.ranking(maxormin * ObjV, LegV, None, SUBPOP)  # 适应度评价
        if PUN_F is not None:
            FitnV = punishing(LegV, FitnV)  # 调用罚函数
        # 记录进化过程
        bestIdx = np.argmax(FitnV)  # 获取最优个体的下标
        if LegV[bestIdx] != 0:
            feasible = np.where(LegV != 0)[0]  # 排除非可行解
            pop_trace[gen, 0] = np.sum(
                ObjV[feasible]) / ObjV[feasible].shape[0]  # 记录种群个体平均目标函数值
            pop_trace[gen, 1] = ObjV[bestIdx]  # 记录当代目标函数的最优值
            var_trace[gen, :] = Chrom[bestIdx, :]  # 记录当代最优的控制变量值
            # 绘制动态图
            if drawing == 2:
                ax = ga.sgaplot(pop_trace[:, [1]], '种群最优个体目标函数值', False, ax,
                                gen)
        else:
            gen -= 1  # 忽略这一代
            badCounter += 1
        if distribute == True:  # 若要增强种群的分布性(可能会造成收敛慢)
            idx = np.argsort(ObjV[:, 0], 0)
            dis = np.diff(ObjV[idx, 0]) / (np.max(ObjV[idx, 0]) - np.min(
                ObjV[idx, 0]) + 1)  # 差分计算距离的修正偏移量
            dis = np.hstack([dis, dis[-1]])
            dis = dis + np.min(dis)  # 修正偏移量+最小量=修正绝对量
            FitnV[idx, 0] *= np.exp(dis)  # 根据相邻距离修改适应度,突出相邻距离大的个体,以增加种群的多样性
        [Chrom, ObjV, LegV] = ga.selecting(selectStyle, Chrom, FitnV, GGAP,
                                           SUBPOP, ObjV, LegV)  # 选择个体生成新一代种群
        gen += 1
    end_time = time.time()  # 结束计时
    times = end_time - start_time
    # 绘图
    if drawing != 0:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.min(pop_trace[:, 1])
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.max(pop_trace[:, 1])
    if np.isnan(best_ObjV):
        raise RuntimeError('error: no feasible solution. (没找到可行解。)')
    print('最优的目标函数值为:', best_ObjV)
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #21
0
def sga_permut_templet(AIM_M,
                       AIM_F,
                       PUN_M,
                       PUN_F,
                       NVAR,
                       VarLen,
                       maxormin,
                       MAXGEN,
                       NIND,
                       SUBPOP,
                       GGAP,
                       selectStyle,
                       recombinStyle,
                       recopt,
                       pm,
                       drawing=1):
    """
sga_permut_templet.py - 单目标编程模板(排列编码)

排列编码即每条染色体的基因都是无重复正整数的编码方式。

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_permut_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,传入该函数前通常由AIM_M = __import__('目标函数名')语句得到
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,传入该函数前通常由PUN_M = __import__('罚函数名')语句得到
    
    PUN_F : str - 罚函数名
    
    NVAR : int - 变量个数,排列编码的染色体长度等于变量个数
    
    VarLen : int - 排列集合的大小
                   例如VarLen = 5表示是从1,2,3,4,5中抽取若干个数排列组成染色体
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,表示子代与父代染色体及性状不相同的概率
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

"""
    """==========================初始化配置==========================="""
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    """=========================开始遗传算法进化======================="""
    #生成初始种群
    Chrom = ga.crtpp(NIND, NVAR, VarLen)
    ObjV = aimfuc(Chrom)  # 求种群的目标函数值

    start_time = time.time()  # 开始计时
    # 开始进化!!
    for gen in range(MAXGEN):
        FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(Chrom, FitnV)  # 调用罚函数
        # 进行遗传算子
        SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
        SelCh = ga.recombin(recombinStyle, Chrom, recopt, SUBPOP)  # 重组
        SelCh = ga.mutpp(SelCh, VarLen, pm)  # 排列编码种群变异
        ObjVSel = aimfuc(SelCh)  # 求后代的目标函数值
        # 重插入
        [Chrom, ObjV] = ga.reins(Chrom, SelCh, SUBPOP, 2, 1, ObjV, ObjVSel)
        pop_trace[gen, 0] = np.sum(ObjV) // ObjV.shape[0]  # 记录种群个体平均目标函数值
        if maxormin == 1:
            pop_trace[gen, 1] = np.min(ObjV)  # 记录当代目标函数的最优值
            var_trace[gen, :] = Chrom[np.argmin(ObjV), :]  # 记录当代最优的控制变量值
        elif maxormin == -1:
            pop_trace[gen, 1] = np.max(ObjV)
            var_trace[gen, :] = Chrom[np.argmax(ObjV), :]  # 记录当代最优的控制变量值
    end_time = time.time()  # 结束计时

    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.min(pop_trace[:, 1]))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.max(pop_trace[:, 1]))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    times = end_time - start_time
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #22
0
파일: main.py 프로젝트: zzxzfy/geatpy
AIM_M = __import__('aimfuc')
PUN_M = __import__('punishing')
"""============================变量设置============================"""
x1 = [-5, 5]; x2 = [2, 10]          # 自变量的范围
b1 = [1, 1] ; b2 = [0, 1]           # 自变量的边界
ranges=np.vstack([x1, x2]).T        # 生成自变量的范围矩阵
borders=np.vstack([b1, b2]).T       # 生成自变量的边界矩阵
"""========================遗传算法参数设置========================="""
NIND = 10;               # 种群规模
MAXGEN = 50;             # 最大遗传代数
GGAP = 0.8;              # 代沟:子代与父代的重复率为(1-GGAP)
selectStyle = 'rws';     # 遗传算法的选择方式设为"rws"——轮盘赌选择
recombinStyle = 'xovdp'  # 遗传算法的重组方式,设为两点交叉
recopt = 0.9;            # 交叉概率
pm = 0.01;               # 变异概率
SUBPOP = 1               # 设置种群数为1
maxormin = 1             # 设置标记表明这是最小化目标
"""=======================调用编程模板进行种群进化==================="""
# 调用编程模板进行种群进化,得到种群进化和变量的追踪器以及运行时间
[pop_trace, var_trace, times] = mintemp1(AIM_M, 'aimfuc', PUN_M, 'punishing', ranges, borders, MAXGEN, NIND, SUBPOP, GGAP, selectStyle, recombinStyle, recopt, pm, maxormin)
"""=========================绘图及输出结果========================="""
# 传入pop_trace进行绘图
gea.trcplot(pop_trace, [['种群最优个体目标函数值'], ['种群个体平均适应度值', '种群最优个体适应度值']])
# 输出结果
best_gen = np.argmin(pop_trace[:, 0]) # 记录最优种群是在哪一代
print('最优的目标函数值为:', np.min(pop_trace[:, 0]))
print('最优的控制变量值为:')
for i in range(var_trace.shape[1]):
	print(var_trace[best_gen, i])
print('最优的一代是第',best_gen + 1,'代')
print('用时:', times, '秒')
예제 #23
0
    def run(self):
        # ==========================初始化配置===========================
        population = self.population  # population是传入的初始化种群
        NIND = population.sizes  # NIND表示的是种群数目
        NVAR = self.problem.Dim  # 得到决策变量的个数
        self.obj_trace = (np.zeros(
            (self.MAXGEN, 2)) * np.nan)  # 定义目标函数值记录器,初始值为nan
        # 目标函数记录器(2列)
        self.var_trace = (np.zeros(
            (self.MAXGEN, NVAR)) * np.nan)  # 定义变量记录器,记录决策变量值,初始值为nan
        # id_trace用于记录每一代训练得出的最佳子种群的ARRAY
        self.forgetCount = 0  # “遗忘策略”计数器,用于记录连续出现最优个体不是可行个体的代数/"遗忘策略"

        x_hang = np.arange(0, NVAR)
        id_1 = np.array([x_hang] * NIND)
        for i in range(NIND):
            np.random.shuffle(id_1[i])
        #id_1 = np.random.randint(0, NVAR, (NIND, NVAR))              # 对index记录的矩阵进行初始化
        # ===========================准备进化============================
        self.timeSlot = time.time()  # 开始计时
        if population.Chrom is None:
            # 如果Chrom是空的话,那么就初始化//Chrom为待解码矩阵
            # population.ObjV = None
            # population.FitnV = np.ones((self.sizes,1))
            # population.CV = np.zeros((self.sizes,1))
            # population.Phen =
            A = int(NVAR / self.n_x)
            e = np.zeros((NIND, NVAR), dtype=np.int)
            for i in range(NIND):
                c = np.arange(0, NVAR)
                batch_size = A
                for j in range(self.n_x):
                    slice_1 = np.random.choice(c.shape[0], batch_size)
                    d = c[slice_1]
                    e[i][d] = (j + 1)
                    c = np.delete(c, slice_1)
                e[i][c] = np.random.randint(1, self.n_x)
            population.Chrom = e
            population.Phen = e
            population.FitnV = np.ones((NVAR, 1))
            population.CV = np.zeros((NVAR, 1))
            population.ObjV = None

            # population.initChrom(NIND)     # 初始化种群染色体矩阵(内含染色体解码,详见Population类的源码)
            # print('初始化Chorm矩阵:', population.Chrom)
            # print('初始化Phen矩阵:', population.Phen)
#        population.ObjV, population.CV = self.problem.aim_chuli(population.Phen, , population.CV) # 计算种群的目标函数值
        population.ObjV, population.CV = self.problem.aim_chuli(
            population.Phen, id_1)  # 计算种群的目标函数值

        # id_1是保留shape的形状
        # 计算种群的目标函数,输入的是CV和Phen表现矩阵
        population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV,
                                      population.CV)  # 计算适应度
        # 自动计算适应度
        #print('种群初始化-2时的适应度:', population.FitnV)
        self.evalsNum = population.sizes  # 记录评价次数
        # 记录评价次数
        # ===========================开始进化============================
        self.currentGen = 0
        # 开始进化,设置currentGen为0
        while self.terminated(population, id_1) == False:
            # 若需要继续进化,那么有
            bestIdx = np.argmax(population.FitnV,
                                axis=0)  # 得到当代的最优个体的索引, 设置axis=0可使得返回一个向量
            studPop = population[np.tile(
                bestIdx, (NIND // 2))]  # 复制最优个体NIND//2份,组成一个“种马种群”
            restPop = population[np.where(
                np.array(range(NIND)) != bestIdx)[0]]  # 得到除去精英个体外其它个体组成的种群
            # 选择个体,以便后面与种马种群进行交配
            tempPop = restPop[ea.selecting(self.selFunc, restPop.FitnV,
                                           (NIND - studPop.sizes))]
            # 将种马种群与选择出来的个体进行合并
            population = studPop + tempPop
            # 进行进化操作
            population.Chrom = ea.recombin(self.recFunc, population.Chrom,
                                           self.pc)  # 重组
            population.Chrom, id_1 = self.problem.intersect(
                population.Chrom, id_1, self.pc)  # 重组
            # population.Chrom = ea.mutate(self.mutFunc, population.Encoding, population.Chrom, population.Field, self.pm)
            # 求进化后个体的目标函数值//变异
            # print('进化中的Chorm矩阵:', population.Chrom)
            # print('进化中的Phen矩阵:', population.Phen)
            population.Phen = population.decoding()  # 染色体解码
            # population.ObjV, population.CV = self.problem.aimFuc(population.Phen, population.CV)
            population.ObjV, population.CV = self.problem.aim_chuli(
                population.Phen, id_1)  # 计算种群的目标函数值
            # population.ObjV, population.CV = self.problem.aim_chuli(population.Chrom, id_1)
            self.evalsNum += population.sizes  # 更新评价次数
            population.FitnV = ea.scaling(self.problem.maxormins *
                                          population.ObjV,
                                          population.CV)  # 计算适应度
        # 处理进化记录器
        delIdx = np.where(np.isnan(self.obj_trace))[0]
        self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
        self.var_trace = np.delete(self.var_trace, delIdx, 0)
        # 对id的trace进行记录
        self.id_trace = np.delete(self.id_trace, delIdx, 0)

        # self.var_trace = np.delete(self.var_trace, delIdx, 0)                       #记录trace
        if self.obj_trace.shape[0] == 0:
            raise RuntimeError(
                'error: No feasible solution. (有效进化代数为0,没找到可行解。)')
        self.passTime += time.time() - self.timeSlot  # 更新用时记录
        # 绘图
        if self.drawing != 0:
            ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
        # 返回最后一代种群、进化记录器、变量记录器以及执行时间

        return [population, self.obj_trace, self.var_trace, self.id_trace]
    start_time = time.time()
    for gen in range(MAXGEN):
        FitnV = ga.ranking(maxormin * ObjV, LegV)
        SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP) 
        SelCh = ga.recombin(recombinStyle, SelCh, recopt, SUBPOP) 
        SelCh = ga.mutbin(SelCh, pm) 
        Phen = ga.bs2rv(SelCh, FieldD) 
        LegVSel = np.ones((SelCh.shape[0], 1)) 
        [ObjVSel, LegVSel, Run] = aimfuc(Phen, LegVSel, Run, NIND)
        [Chrom, ObjV, LegV] = ga.reins(Chrom, SelCh, SUBPOP, 1, 1, maxormin*ObjV, maxormin*ObjVSel, ObjV, ObjVSel, LegV, LegVSel)
        pop_trace[gen, 1] = np.sum(ObjV)/ObjV.shape[0]
        if maxormin == 1:
            best_ind = np.argmin(ObjV)
        elif maxormin == -1:
            best_ind = np.argmax(ObjV)
        pop_trace[gen, 0] = ObjV[best_ind]
        ind_trace[gen, :] = Chrom[best_ind, :]
    
    end_time = time.time()
    ga.trcplot(pop_trace,[['Best Individual Fitness', 'Population Average Fintess']], ['Result'])
    
#===============================================================================
# Output
    best_gen = np.argmin(pop_trace[:, 0])
    print('Optimal Fitness:', np.min(pop_trace[:, 0]))
    print('Optimal Variables:')
    variables = ga.bs2rv(ind_trace, FieldD)
    for i in range(variables.shape[1]):
        print(variables[best_gen,i])
    print('The best generation is', best_gen + 1, 'th generation')
    print('Time Spent:', end_time - start_time, 'seconds')
예제 #25
0
Chrom = ea.crtbp(NIND, Lind)  # 生成种群染色体矩阵
variable = ea.bs2real(Chrom, FieldD)  # 对初始种群进行解码
ObjV = aim(variable)  # 计算初始种群个体的目标函数值
best_ind = np.argmax(ObjV)  # 计算当代最优个体的序号
# 开始进化
for gen in range(MAXGEN):
    FitnV = ea.ranking(-ObjV)  # 根据目标函数大小分配适应度值(由于遵循目标最小化约定,因此最大化问题要对目标函数值乘上-1)
    SelCh = Chrom[ea.selecting('rws', FitnV, NIND - 1), :]  # 选择,采用'rws'轮盘赌选择
    SelCh = ea.recombin('xovsp', SelCh, 0.7)  # 重组(采用两点交叉方式,交叉概率为0.7)
    SelCh = ea.mutbin(Encoding, SelCh)  # 二进制种群变异
    # 把父代精英个体与子代合并
    Chrom = np.vstack([Chrom[best_ind, :], SelCh])
    variable = ea.bs2real(Chrom, FieldD)  # 对育种种群进行解码(二进制转十进制)
    ObjV = aim(variable)  # 求育种个体的目标函数值
    # 记录
    best_ind = np.argmax(ObjV)  # 计算当代最优个体的序号
    obj_trace[gen, 0] = np.sum(ObjV) / NIND  # 记录当代种群的目标函数均值
    obj_trace[gen, 1] = ObjV[best_ind]  # 记录当代种群最优个体目标函数值
    var_trace[gen, :] = Chrom[best_ind, :]  # 记录当代种群最优个体的变量值
# 进化完成
end_time = time.time()  # 结束计时
"""============================输出结果及绘图================================"""
best_gen = np.argmax(obj_trace[:, [1]])
print('目标函数最大值:', obj_trace[best_gen, 1])  # 输出目标函数最大值
variable = ea.bs2real(var_trace[[best_gen], :], FieldD)  # 解码得到表现型
print('对应的决策变量值为:')
print(variable[0][0])  # 因为此处variable是一个矩阵,因此用[0][0]来取出里面的元素
print('用时:', end_time - start_time)
plt.plot(variable, aim(variable), 'bo')
ea.trcplot(obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
예제 #26
0
def sga_code_templet(AIM_M,
                     AIM_F,
                     PUN_M,
                     PUN_F,
                     FieldD,
                     problem,
                     maxormin,
                     MAXGEN,
                     NIND,
                     SUBPOP,
                     GGAP,
                     selectStyle,
                     recombinStyle,
                     recopt,
                     pm,
                     drawing=1):
    """
sga_code_templet.py - 单目标编程模板(二进制/格雷编码)

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_code_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:f = aimfuc(Phen)
            其中Phen是种群的表现型矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: f = punishing(Phen, FitnV)
            其中Phen是种群的表现型矩阵, FitnV为种群个体适应度列向量
    
    PUN_F : str - 罚函数名
    
    FieldD : array  - 二进制/格雷码种群区域描述器,
        描述种群每个个体的染色体长度和如何解码的矩阵,它有以下结构:
                    
        [lens;		(int) 每个控制变量编码后在染色体中所占的长度
         lb;		(float) 指明每个变量使用的下界
         ub;		(float) 指明每个变量使用的上界
         codes;	(0:binary     | 1:gray) 指明子串是怎么编码的,
                                          0为标准二进制编码,1为各类编码
         scales;  (0: rithmetic | 1:logarithmic) 指明每个子串是否使用对数或算术刻度, 
                                                 1为使用对数刻度,2为使用算术刻度
         lbin;		(0:excluded   | 1:included)
         ubin]		(0:excluded   | 1:included)
                
        lbin和ubin指明范围中是否包含每个边界。
        选择lbin=0或ubin=0,表示范围中不包含相应边界。
        选择lbin=1或ubin=1,表示范围中包含相应边界。
    
    problem : str - 表明是整数问题还是实数问题,'I'表示是整数问题,'R'表示是实数问题                 
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,表示子代与父代染色体及性状不相同的概率
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:
        ObjV = aimfuc(Phen), 其中Phen表示种群的表现型矩阵
    2.本模板调用的罚函数形如: 
        [FitnV, punIdx] = punishing(Phen, FitnV), 
        其中输入参数的FitnV为惩罚前的适应度,输出参数的FitnV为惩罚后的适应度
        punIdx为惩罚的个体所在的下标
      在罚函数定义中,必须将不满足约束条件的个体对应的适应度设为0,否则请修改模板使用

"""

    #==========================初始化配置==========================="""
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    exIdx = np.array([])  # 存储非可行解的下标
    NVAR = FieldD.shape[1]  # 得到控制变量的个数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    """=========================开始遗传算法进化======================="""
    Lind = np.sum(FieldD[0, :])  # 种群染色体长度
    Chrom = ga.crtbp(NIND, Lind)  # 生成初始种群
    if problem == 'R':
        variable = ga.bs2rv(Chrom, FieldD)  # 解码
    elif problem == 'I':
        if np.any(FieldD >= sys.maxsize):
            variable = ga.bs2int(Chrom, FieldD).astype('object')  # 解码
        else:
            variable = ga.bs2int(Chrom, FieldD).astype('int64')  # 解码
    ObjV = aimfuc(variable)  # 求种群的目标函数值

    start_time = time.time()  # 开始计时
    # 开始进化!!
    for gen in range(MAXGEN):
        FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)
        if PUN_F is not None:
            [FitnV, exIdx] = punishing(Chrom, FitnV)  # 调用罚函数
        # 记录进化过程
        bestIdx = np.argmax(FitnV)  # 获取最优个体的下标
        wrongSign = np.ones((FitnV.shape[0], 1))
        wrongSign[list(exIdx)] = 0  # 对非可行解作标记
        if wrongSign[bestIdx] != 0:
            feasible = np.where(wrongSign != 0)[0]  # 排除非可行解
            pop_trace[gen, 0] = np.sum(
                ObjV[feasible]) / ObjV[feasible].shape[0]  # 记录种群个体平均目标函数值
            pop_trace[gen, 1] = ObjV[bestIdx]  # 记录当代目标函数的最优值
            var_trace[gen, :] = variable[bestIdx, :]  # 记录当代最优的控制变量值
        # 进行遗传算子
        SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
        SelCh = ga.recombin(recombinStyle, Chrom, recopt, SUBPOP)  # 重组
        SelCh = ga.mutbin(SelCh, pm)  # 变异
        # 计算种群适应度
        if problem == 'R':
            variable = ga.bs2rv(SelCh, FieldD)  # 解码
        elif problem == 'I':
            if np.any(FieldD >= sys.maxsize):
                variable = ga.bs2int(SelCh, FieldD).astype('object')  # 解码
            else:
                variable = ga.bs2int(SelCh, FieldD).astype('int64')
        ObjVSel = aimfuc(variable)  # 求后代的目标函数值
        # 重插入
        [Chrom, ObjV] = ga.reins(Chrom, SelCh, SUBPOP, 2, 1, ObjV, ObjVSel)
        # 计算新一代种群的控制变量解码值
        if problem == 'R':
            variable = ga.bs2rv(Chrom, FieldD)  # 解码
        elif problem == 'I':
            if np.any(FieldD >= sys.maxsize):
                variable = ga.bs2int(Chrom, FieldD).astype('object')  # 解码
            else:
                variable = ga.bs2int(SelCh, FieldD).astype('int64')
    end_time = time.time()  # 结束计时
    # 后处理进化记录器
    delIdx = np.where(np.isnan(pop_trace))[0]
    pop_trace = np.delete(pop_trace, delIdx, 0)
    var_trace = np.delete(var_trace, delIdx, 0)
    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.min(pop_trace[:, 1]))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.max(pop_trace[:, 1]))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    times = end_time - start_time
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #27
0
    def run(self):
        # ==========================初始化配置===========================
        population = self.population      # population是传入的初始化种群
        NIND = population.sizes           # NIND表示的是种群数目
        NVAR = self.problem.Dim           # 得到决策变量的个数
        self.obj_trace = (np.zeros((self.MAXGEN, 2)) * np.nan)       # 定义目标函数值记录器,初始值为nan
        # 目标函数记录器(2列)
        self.var_trace = (np.zeros((self.MAXGEN, NVAR)) * np.nan)    # 定义变量记录器,记录决策变量值,初始值为nan
        # id_trace用于记录每一代训练得出的最佳子种群的ARRAY
        self.forgetCount = 0    # “遗忘策略”计数器,用于记录连续出现最优个体不是可行个体的代数/"遗忘策略"
        id_1 = self.id_1_start()
        #id_1 = np.random.randint(0, NVAR, (NIND, NVAR))              # 对index记录的矩阵进行初始化
        # ===========================准备进化============================
        self.timeSlot = time.time()                                  # 开始计时
        if population.Chrom is None:
            new_fixed_dict = self.change_bug()
            population.Chrom, population.Phen, population.FitnV, population.CV, population.ObjV = self.start_fx()
            population.ObjV, population.CV = self.problem.aim_chuli(population.Phen, id_1, new_fixed_dict)
            feasible = np.where(np.all(population.CV <= 0, 1))[0]
            while True:
                if len(feasible) > 0:
                    break
                else:
                    # population.Chrom, population.Phen, population.FitnV, population.CV, population.ObjV = self.start_fx()
                    # id_1 = self.id_1_start()
                    new_fixed_dict = self.change_bug()
                    population.ObjV, population.CV = self.problem.aim_chuli(population.Phen, id_1, new_fixed_dict)
                    feasible = np.where(np.all(population.CV <= 0, 1))[0]

        # id_1是保留shape的形状
        # 计算种群的目标函数,输入的是CV和Phen表现矩阵
        population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV, population.CV)  # 计算适应度
        # 自动计算适应度
        #print('种群初始化-2时的适应度:', population.FitnV)
        self.evalsNum = population.sizes     # 记录评价次数
        # 记录评价次数
        # ===========================开始进化============================
        self.currentGen = 0
        # 开始进化,设置currentGen为0
        while self.terminated(population, id_1) == False:
            # 若需要继续进化,那么有

            bestIdx = np.argmax(population.FitnV, axis=0)  # 得到当代的最优个体的索引, 设置axis=0可使得返回一个向量
            best_id = np.tile(id_1[bestIdx], (NIND // 2, 1))
            studPop = population[np.tile(bestIdx, NIND // 2)]  # 复制最优个体NIND//2份,组成一个“种马种群”
            restPop = population[np.where(np.array(range(NIND)) != bestIdx)[0]]
            # 得到除去精英个体外其它个体组成的种群
            # 选择个体,以便后面与种马种群进行交配
            restid = id_1[np.where(np.array(range(NIND)) != bestIdx)[0]]
            id_temp = restid[ea.selecting(self.selFunc, restPop.FitnV, (NIND - studPop.sizes))]
            tempPop = restPop[ea.selecting(self.selFunc, restPop.FitnV, (NIND - studPop.sizes))]
            # 将种马种群与选择出来的个体进行合并
            population = studPop + tempPop
            id_1 = np.vstack((best_id, id_temp))
            # 进行进化操作
            # population.Chrom = ea.recombin(self.recFunc, population.Chrom, self.pc)                  # 重组
            population.Chrom, id_1 = self.problem.intersect(population.Chrom, id_1, self.pc)  # 重组
            population.Chrom = ea.mutate(self.mutFunc, population.Encoding, population.Chrom, population.Field, self.pm)
            # 求进化后个体的目标函数值//变异
            # print('进化中的Chorm矩阵:', population.Chrom)
            # print('进化中的Phen矩阵:', population.Phen)
            population.Phen = population.decoding()  # 染色体解码
            # population.ObjV, population.CV = self.problem.aimFuc(population.Phen, population.CV)
            population.ObjV, population.CV = self.problem.aim_chuli(population.Phen, id_1, new_fixed_dict)  # 计算种群的目标函数值
            # population.ObjV, population.CV = self.problem.aim_chuli(population.Chrom, id_1)
            self.evalsNum += population.sizes
            population.FitnV = ea.scaling(self.problem.maxormins * population.ObjV, population.CV)  # 计算适应度
        # 处理进化记录器
        # 计算适应度
        # 处理进化记录器
        delIdx = np.where(np.isnan(self.obj_trace))[0]
        self.obj_trace = np.delete(self.obj_trace, delIdx, 0)
        self.var_trace = np.delete(self.var_trace, delIdx, 0)
        # 对id的trace进行记录
        self.id_trace = np.delete(self.id_trace, delIdx, 0)

       # self.var_trace = np.delete(self.var_trace, delIdx, 0)                       #记录trace
        if self.obj_trace.shape[0] == 0:
            raise RuntimeError('error: No feasible solution. (有效进化代数为0,没找到可行解。)')
        self.passTime += time.time() - self.timeSlot # 更新用时记录
        # 绘图
        if self.drawing != 0:
            ea.trcplot(self.obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
        # 返回最后一代种群、进化记录器、变量记录器以及执行时间

        return [population, self.obj_trace, self.var_trace, self.id_trace, new_fixed_dict]
예제 #28
0
def main():
    """============================变量设置============================"""
    x1 = [50, 100]  # 第一个决策变量范围
    x2 = [50, 100]  # 第二个决策变量范围
    x3 = [50, 100]
    x4 = [50, 100]
    x5 = [50, 100]
    x6 = [50, 100]
    x7 = [50, 100]
    x8 = [50, 100]
    x9 = [50, 100]
    x10 = [50, 100]

    b1 = [1, 1]  # 第一个决策变量边界,1表示包含范围的边界,0表示不包含
    b2 = [1, 1]  # 第二个决策变量边界,1表示包含范围的边界,0表示不包含
    b3 = [1, 1]
    b4 = [1, 1]
    b5 = [1, 1]
    b6 = [1, 1]
    b7 = [1, 1]
    b8 = [1, 1]
    b9 = [1, 1]
    b10 = [1, 1]

    ranges = np.vstack([x1, x2, x3, x4, x5, x6, x7, x8, x9,
                        x10]).T  # 生成自变量的范围矩阵,使得第一行为所有决策变量的下界,第二行为上界
    borders = np.vstack([b1, b2, b3, b4, b5, b6, b7, b8, b9,
                         b10]).T  # 生成自变量的边界矩阵
    varTypes = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])  # 决策变量的类型,0表示连续,1表示离散
    """==========================染色体编码设置========================="""
    Encoding = 'BG'  # 'BG'表示采用二进制/格雷编码
    codes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 决策变量的编码方式,设置两个0表示两个决策变量均使用二进制编码
    precisions = [4, 4, 4, 4, 4, 4, 4, 4, 4,
                  4]  # 决策变量的编码精度,表示二进制编码串解码后能表示的决策变量的精度可达到小数点后6位
    scales = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 0表示采用算术刻度,1表示采用对数刻度
    FieldD = ea.crtfld(Encoding, varTypes, ranges, borders, precisions, codes,
                       scales)  # 调用函数创建译码矩阵
    """=========================遗传算法参数设置========================"""
    NIND = 30  # 种群个体数目
    MAXGEN = 30  # 最大遗传代数
    maxormins = [1]  # 列表元素为1则表示对应的目标函数是最小化,元素为-1则表示对应的目标函数是最大化
    selectStyle = 'rws'  # 采用轮盘赌选择
    recStyle = 'xovdp'  # 采用两点交叉
    mutStyle = 'mutbin'  # 采用二进制染色体的变异算子
    pc = 0.7  # 交叉概率
    pm = 1  # 整条染色体的变异概率(每一位的变异概率=pm/染色体长度)
    Lind = int(np.sum(FieldD[0, :]))  # 计算染色体长度
    obj_trace = np.zeros((MAXGEN, 2))  # 定义目标函数值记录器
    var_trace = np.zeros((MAXGEN, Lind))  # 染色体记录器,记录历代最优个体的染色体
    """=========================开始遗传算法进化========================"""
    start_time = time.time()  # 开始计时
    Chrom = ea.crtpc(Encoding, NIND, FieldD)  # 生成种群染色体矩阵
    variable = ea.bs2real(Chrom, FieldD)  # 对初始种群进行解码
    ObjV = minfun(variable)  # 计算初始种群个体的目标函数值
    FitnV = ea.ranking(maxormins * ObjV)  # 根据目标函数大小分配适应度值
    best_ind = np.argmax(FitnV)  # 计算当代最优个体的序号
    # 开始进化
    for gen in range(MAXGEN):
        print(gen)
        SelCh = Chrom[ea.selecting(selectStyle, FitnV, NIND - 1), :]  # 选择
        SelCh = ea.recombin(recStyle, SelCh, pc)  # 重组
        SelCh = ea.mutate(mutStyle, Encoding, SelCh, pm)  # 变异
        # 把父代精英个体与子代的染色体进行合并,得到新一代种群
        Chrom = np.vstack([Chrom[best_ind, :], SelCh])
        Phen = ea.bs2real(Chrom, FieldD)  # 对种群进行解码(二进制转十进制)
        print(Phen)
        ObjV = minfun(Phen)  # 求种群个体的目标函数值
        FitnV = ea.ranking(maxormins * ObjV)  # 根据目标函数大小分配适应度值
        # 记录
        best_ind = np.argmax(FitnV)  # 计算当代最优个体的序号
        obj_trace[gen, 0] = np.sum(ObjV) / ObjV.shape[0]  # 记录当代种群的目标函数均值
        obj_trace[gen, 1] = ObjV[best_ind]  # 记录当代种群最优个体目标函数值
        var_trace[gen, :] = Chrom[best_ind, :]  # 记录当代种群最优个体的染色体
        print(best_ind)
    # 进化完成
    end_time = time.time()  # 结束计时
    ea.trcplot(obj_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])  # 绘制图像
    """============================输出结果============================"""
    best_gen = np.argmin(obj_trace[:, [1]])
    print('最优解的目标函数值:', obj_trace[best_gen, 1])
    variable = ea.bs2real(var_trace[[best_gen], :],
                          FieldD)  # 解码得到表现型(即对应的决策变量值)
    print('最优解的决策变量值为:')
    print(variable)
    print('用时:', end_time - start_time, '秒')
예제 #29
0
def sga_real_templet(AIM_M,
                     AIM_F,
                     PUN_M,
                     PUN_F,
                     FieldDR,
                     problem,
                     maxormin,
                     MAXGEN,
                     NIND,
                     SUBPOP,
                     GGAP,
                     selectStyle,
                     recombinStyle,
                     recopt,
                     pm,
                     distribute,
                     drawing=1):
    """
sga_real_templet.py - 单目标编程模板(实值编码)

语法:
    该函数除了参数drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_real_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,由AIM_M = __import__('目标函数所在文件名')语句得到
            目标函数规范定义:[f,LegV] = aimfuc(Phen,LegV)
            其中Phen是种群的表现型矩阵, LegV为种群的可行性列向量,f为种群的目标函数值矩阵
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,由PUN_M = __import__('罚函数所在文件名')语句得到
            罚函数规范定义: newFitnV = punishing(LegV, FitnV)
            其中LegV为种群的可行性列向量, FitnV为种群个体适应度列向量
            一般在罚函数中对LegV为0的个体进行适应度惩罚,返回修改后的适应度列向量newFitnV
    
    PUN_F : str - 罚函数名
    
    FieldDR : array - 实际值种群区域描述器
        [lb;		(float) 指明每个变量使用的下界
         ub]		(float) 指明每个变量使用的上界
         注:不需要考虑是否包含变量的边界值。在crtfld中已经将是否包含边界值进行了处理
         本函数生成的矩阵的元素值在FieldDR的[下界, 上界)之间
    
    problem : str - 表明是整数问题还是实数问题,'I'表示是整数问题,'R'表示是实数问题                 
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,表示子代与父代染色体及性状不相同的概率
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    distribute : bool - 是否增强种群的分布性(可能会造成收敛慢)
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

模板使用注意:
    1.本模板调用的目标函数形如:[ObjV,LegV] = aimfuc(Phen,LegV), 
      其中Phen表示种群的表现型矩阵, LegV为种群的可行性列向量(详见Geatpy数据结构)
    2.本模板调用的罚函数形如: newFitnV = punishing(LegV, FitnV), 
      其中FitnV为用其他算法求得的适应度
    若不符合上述规范,则请修改算法模板或自定义新算法模板
    3.关于'maxormin': geatpy的内核函数全是遵循“最小化目标”的约定的,即目标函数值越小越好。
      当需要优化最大化的目标时,需要设置'maxormin'为-1。
      本算法模板是正确使用'maxormin'的典型范例,其具体用法如下:
      当调用的函数传入参数包含与“目标函数值矩阵”有关的参数(如ObjV,ObjVSel,NDSetObjV等)时,
      查看该函数的参考资料(可用'help'命令查看,也可到官网上查看相应的教程),
      里面若要求传入前对参数乘上'maxormin',则需要乘上。
      里面若要求对返回参数乘上'maxormin'进行还原,
      则调用函数返回得到的相应参数需要乘上'maxormin'进行还原,否则其正负号就会被改变。

"""
    """==========================初始化配置==========================="""
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F)  # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F)  # 获得罚函数
    NVAR = FieldDR.shape[1]  # 得到控制变量的个数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN, 2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN, NVAR)) * np.nan)
    ax = None  # 存储上一帧图形
    repnum = 0  # 初始化重复个体数为0
    """=========================开始遗传算法进化======================="""
    if problem == 'R':
        Chrom = ga.crtrp(NIND, FieldDR)  # 生成初始种群
    elif problem == 'I':
        Chrom = ga.crtip(NIND, FieldDR)
    LegV = np.ones((NIND, 1))  # 初始化种群的可行性列向量
    [ObjV, LegV] = aimfuc(Chrom, LegV)  # 求种群的目标函数值
    gen = 0
    badCounter = 0  # 用于记录在“遗忘策略下”被忽略的代数
    # 开始进化!!
    start_time = time.time()  # 开始计时
    while gen < MAXGEN:
        if badCounter >= 10 * MAXGEN:  # 若多花了10倍的迭代次数仍没有可行解出现,则跳出
            break
        FitnV = ga.ranking(maxormin * ObjV, LegV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(LegV, FitnV)  # 调用罚函数
        # 记录进化过程
        bestIdx = np.argmax(FitnV)  # 获取最优个体的下标
        if LegV[bestIdx] != 0:
            feasible = np.where(LegV != 0)[0]  # 排除非可行解
            pop_trace[gen, 0] = np.sum(
                ObjV[feasible]) / ObjV[feasible].shape[0]  # 记录种群个体平均目标函数值
            pop_trace[gen, 1] = ObjV[bestIdx]  # 记录当代目标函数的最优值
            var_trace[gen, :] = Chrom[bestIdx, :]  # 记录当代最优的控制变量值
            repnum = len(
                np.where(ObjV[np.argmax(FitnV)] == ObjV)[0])  # 计算最优个体重复数
            # 绘制动态图
            if drawing == 2:
                ax = ga.sgaplot(pop_trace[:, [1]], '种群最优个体目标函数值', False, ax,
                                gen)
            badCounter = 0  # badCounter计数器清零
        else:
            gen -= 1  # 忽略这一代(遗忘策略)
            badCounter += 1
        if distribute == True:  # 若要增强种群的分布性(可能会造成收敛慢)
            idx = np.argsort(ObjV[:, 0], 0)
            dis = np.diff(ObjV[idx, 0]) / (np.max(ObjV[idx, 0]) - np.min(
                ObjV[idx, 0]) + 1)  # 差分计算距离的修正偏移量
            dis = np.hstack([dis, dis[-1]])
            dis = dis + np.min(dis)  # 修正偏移量+最小量=修正绝对量
            FitnV[idx, 0] *= np.exp(dis)  # 根据相邻距离修改适应度,突出相邻距离大的个体,以增加种群的多样性
        # 进行遗传算子
        SelCh = ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP)  # 选择
        SelCh = ga.recombin(recombinStyle, SelCh, recopt, SUBPOP)  # 对所选个体进行重组
        if problem == 'R':
            SelCh = ga.mutbga(SelCh, FieldDR, pm)  # 变异
            if repnum > Chrom.shape[0] * 0.01:  # 当最优个体重复率高达1%时,进行一次高斯变异
                SelCh = ga.mutgau(SelCh, FieldDR, pm)  # 高斯变异
        elif problem == 'I':
            SelCh = ga.mutint(SelCh, FieldDR, pm)
        LegVSel = np.ones((SelCh.shape[0], 1))  # 初始化育种种群的可行性列向量
        [ObjVSel, LegVSel] = aimfuc(SelCh, LegVSel)  # 求育种种群的目标函数值
        FitnVSel = ga.ranking(maxormin * ObjVSel, LegVSel, None,
                              SUBPOP)  # 计算育种种群的适应度
        if PUN_F is not None:
            FitnVSel = punishing(LegVSel, FitnVSel)  # 调用罚函数
        # 重插入
        [Chrom, ObjV, LegV] = ga.reins(Chrom, SelCh, SUBPOP, 1, 1, FitnV,
                                       FitnVSel, ObjV, ObjVSel, LegV, LegVSel)
        gen += 1
    end_time = time.time()  # 结束计时
    times = end_time - start_time
    # 后处理进化记录器
    delIdx = np.where(np.isnan(pop_trace))[0]
    pop_trace = np.delete(pop_trace, delIdx, 0)
    var_trace = np.delete(var_trace, delIdx, 0)
    if pop_trace.shape[0] == 0:
        raise RuntimeError('error: no feasible solution. (有效进化代数为0,没找到可行解。)')
    # 绘图
    if drawing != 0:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.min(pop_trace[:, 1])
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1])  # 记录最优种群是在哪一代
        best_ObjV = np.max(pop_trace[:, 1])
    print('最优的目标函数值为:%s' % (best_ObjV))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('有效进化代数:%s' % (pop_trace.shape[0]))
    print('最优的一代是第 %s 代' % (best_gen + 1))
    print('时间已过 %s 秒' % (times))
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]
예제 #30
0
def sga_new_real_templet(AIM_M, AIM_F, PUN_M, PUN_F, FieldDR, problem, maxormin, MAXGEN, NIND, SUBPOP, GGAP, selectStyle, recombinStyle, recopt, pm, drawing = 1):
    
    """
sga_new_real_templet.py - 改进的单目标编程模板(实值编码)

本模板实现改进单目标编程模板(实值编码),将父子两代合并进行选择,增加了精英保留机制

语法:
    该函数除了drawing外,不设置可缺省参数。当某个参数需要缺省时,在调用函数时传入None即可。
    比如当没有罚函数时,则在调用编程模板时将第3、4个参数设置为None即可,如:
    sga_new_real_templet(AIM_M, 'aimfuc', None, None, ..., maxormin)

输入参数:
    AIM_M - 目标函数的地址,传入该函数前通常由AIM_M = __import__('目标函数名')语句得到
    
    AIM_F : str - 目标函数名
    
    PUN_M - 罚函数的地址,传入该函数前通常由PUN_M = __import__('罚函数名')语句得到
    
    PUN_F : str - 罚函数名
    
    FieldDR : array - 实际值种群区域描述器
        [lb;		(float) 指明每个变量使用的下界
         ub]		(float) 指明每个变量使用的上界
         注:不需要考虑是否包含变量的边界值。在crtfld中已经将是否包含边界值进行了处理
         本函数生成的矩阵的元素值在FieldDR的[下界, 上界)之间
    
    problem : str - 表明是整数问题还是实数问题,'I'表示是整数问题,'R'表示是实数问题                 
    
    maxormin int - 最小最大化标记,1表示目标函数最小化;-1表示目标函数最大化
    
    MAXGEN : int - 最大遗传代数
    
    NIND : int - 种群规模,即种群中包含多少个个体
    
    SUBPOP : int - 子种群数量,即对一个种群划分多少个子种群
    
    GGAP : float - 代沟,本模板中该参数为无用参数,仅为了兼容同类的其他模板而设
    
    selectStyle : str - 指代所采用的低级选择算子的名称,如'rws'(轮盘赌选择算子)
    
    recombinStyle: str - 指代所采用的低级重组算子的名称,如'xovsp'(单点交叉)
    
    recopt : float - 交叉概率
    
    pm : float - 重组概率
    
    drawing : int - (可选参数),0表示不绘图,1表示绘制最终结果图。默认drawing为1

输出参数:
    pop_trace : array - 种群进化记录器(进化追踪器),
                        第0列记录着各代种群最优个体的目标函数值
                        第1列记录着各代种群的适应度均值
                        第2列记录着各代种群最优个体的适应度值
    
    var_trace : array - 变量记录器,记录着各代种群最优个体的变量值,每一列对应一个控制变量
    
    times     : float - 进化所用时间

"""
    """==========================初始化配置==========================="""
    GGAP = 0.5 # 因为父子合并后选择,因此要将代沟设为0.5以维持种群规模
    # 获取目标函数和罚函数
    aimfuc = getattr(AIM_M, AIM_F) # 获得目标函数
    if PUN_F is not None:
        punishing = getattr(PUN_M, PUN_F) # 获得罚函数
    NVAR = FieldDR.shape[1] # 得到控制变量的个数
    # 定义进化记录器,初始值为nan
    pop_trace = (np.zeros((MAXGEN ,2)) * np.nan)
    # 定义变量记录器,记录控制变量值,初始值为nan
    var_trace = (np.zeros((MAXGEN ,NVAR)) * np.nan) 
    """=========================开始遗传算法进化======================="""
    if problem == 'R':
        Chrom = ga.crtrp(NIND, FieldDR) # 生成初始种群
    elif problem == 'I':
        Chrom = ga.crtip(NIND, FieldDR)
    
    start_time = time.time() # 开始计时
    # 开始进化!!
    for gen in range(MAXGEN):
        # 进行遗传算子,生成子代
        SelCh=ga.recombin(recombinStyle, Chrom, recopt, SUBPOP) # 重组
        if problem == 'R':
            SelCh=ga.mutbga(SelCh,FieldDR, pm) # 变异
        elif problem == 'I':
            SelCh=ga.mutint(SelCh, FieldDR, pm)
        Chrom = np.vstack([Chrom, SelCh]) # 父子合并
        ObjV = aimfuc(Chrom) # 求后代的目标函数值
        pop_trace[gen,0] = np.sum(ObjV) / ObjV.shape[0] # 记录种群个体平均目标函数值
        if maxormin == 1:
            pop_trace[gen,1] = np.min(ObjV) # 记录当代目标函数的最优值
            var_trace[gen,:] = Chrom[np.argmin(ObjV), :] # 记录当代最优的控制变量值
        elif maxormin == -1:
            pop_trace[gen,1] = np.max(ObjV)
            var_trace[gen,:] = Chrom[np.argmax(ObjV), :] # 记录当代最优的控制变量值
        # 最后对合并的种群进行适应度评价并选出一半个体留到下一代
        FitnV = ga.ranking(maxormin * ObjV, None, SUBPOP)
        if PUN_F is not None:
            FitnV = punishing(Chrom, FitnV) # 调用罚函数
        Chrom=ga.selecting(selectStyle, Chrom, FitnV, GGAP, SUBPOP) # 选择
    end_time = time.time() # 结束计时
    
    # 绘图
    if drawing == 1:
        ga.trcplot(pop_trace, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
    # 输出结果
    if maxormin == 1:
        best_gen = np.argmin(pop_trace[:, 1]) # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.min(pop_trace[:, 1]))
    elif maxormin == -1:
        best_gen = np.argmax(pop_trace[:, 1]) # 记录最优种群是在哪一代
        print('最优的目标函数值为:', np.max(pop_trace[:, 1]))
    print('最优的控制变量值为:')
    for i in range(NVAR):
        print(var_trace[best_gen, i])
    print('最优的一代是第', best_gen + 1, '代')
    times = end_time - start_time
    print('时间已过', times, '秒')
    # 返回进化记录器、变量记录器以及执行时间
    return [pop_trace, var_trace, times]