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)
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]
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]
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]
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))
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)
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]
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]])
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)
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]
# 开始进化!! 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, '秒')
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]
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]
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]
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]
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, '秒')
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]
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)
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]
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]
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]
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, '秒')
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')
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, [['种群个体平均目标函数值', '种群最优个体目标函数值']])
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]
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]
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, '秒')
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]
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]