def run(self): #==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法模板的一些动态参数 #===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 refPoint = np.vstack([uniformPoint, np.random.rand(NIND, self.problem.M)]) # 初始化参考点(详见注释中的参考文献) if population.Chrom is None or population.sizes != NIND: population.initChrom(NIND) # 初始化种群染色体矩阵(内含解码,详见Population类的源码),此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 else: population.Phen = population.decoding() # 染色体解码 self.problem.aimFunc(population) # 计算种群的目标函数值 self.evalsNum = population.sizes # 记录评价次数 #===========================开始进化============================ while self.terminated(population) == False: # 选择个体参与进化 offspring = population[ea.selecting(self.selFunc, population.FitnV, NIND)] # 对选出的个体进行进化操作 offspring.Chrom = self.recOper.do(offspring.Chrom) # 重组 offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 变异 offspring.Phen = offspring.decoding() # 解码 self.problem.aimFunc(offspring) # 求进化后个体的目标函数值 self.evalsNum += offspring.sizes # 更新评价次数 # 重插入生成新一代种群 population = self.reinsertion(population, offspring, refPoint) # 修改refPoint refPoint[NIND:, :] = self.renewRefPoint(population.ObjV, refPoint[NIND:, :]) if (self.currentGen) % np.ceil(self.fr * self.MAXGEN) == 0: refPoint[:NIND, :] = uniformPoint * (np.max(population.ObjV, 0) - np.min(population.ObjV, 0)) # 后续处理,限制种群规模(因为此时种群规模有可能大于NIND) [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NIND, None, population.CV) # 对NIND个个体进行非支配分层 population = population[ea.refselect(self.problem.maxormins * population.ObjV, levels, criLevel, NIND, uniformPoint)] # 根据参考点选择个体 return self.finishing(population) # 调用finishing完成后续工作并返回结果
def reinsertion(self, population, offspring, NUM, uniformPoint): """ 描述: 重插入个体产生新一代种群(采用父子合并选择的策略)。 NUM为所需要保留到下一代的个体数目。 """ # 父子两代合并 population = population + offspring # 选择个体保留到下一代 [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NUM, None, population.CV) # 对NUM个个体进行非支配分层 chooseFlag = ea.refselect(self.problem.maxormins * population.ObjV, levels, criLevel, NUM, uniformPoint, True) # 根据参考点选择个体(True表示使用伪随机数方法,可以提高速度,详见refselect帮助文档) return population[chooseFlag]
def run(self, prophetPop=None): # prophetPop为先知种群(即包含先验知识的种群) #==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法模板的一些动态参数 #===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 refPoint = np.vstack( [uniformPoint, np.random.rand(NIND, self.problem.M)]) # 初始化参考点(详见注释中的参考文献) population.initChrom( NIND ) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 self.call_aimFunc(population) # 计算种群的目标函数值 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查,故应确保prophetPop是一个种群类且拥有合法的Chrom、ObjV、Phen等属性) if prophetPop is not None: print('本算法需谨慎使用先验知识,有可能会导致结果比先验知识差。') population = (prophetPop + population)[:NIND] # 插入先知种群 #===========================开始进化============================ while self.terminated(population) == False: # 选择个体参与进化 offspring = population[ea.selecting(self.selFunc, population.FitnV, NIND)] # 进行进化操作,分别对各个种群染色体矩阵进行重组和变异 for i in range(population.ChromNum): offspring.Chroms[i] = self.recOpers[i].do( offspring.Chroms[i]) # 重组 offspring.Chroms[i] = self.mutOpers[i].do( offspring.Encodings[i], offspring.Chroms[i], offspring.Fields[i]) # 变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 population = self.reinsertion(population, offspring, refPoint) # 重插入生成新一代种群 # 修改refPoint refPoint[NIND:, :] = self.renewRefPoint(population.ObjV, refPoint[NIND:, :]) if (self.currentGen) % np.ceil(self.fr * self.MAXGEN) == 0: refPoint[:NIND, :] = uniformPoint * ( np.max(population.ObjV, 0) - np.min(population.ObjV, 0)) # 后续处理,限制种群规模(因为此时种群规模有可能大于NIND) [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NIND, None, population.CV) # 对NIND个个体进行非支配分层 population = population[ea.refselect( self.problem.maxormins * population.ObjV, levels, criLevel, NIND, uniformPoint)] # 根据参考点选择个体 return self.finishing(population) # 调用finishing完成后续工作并返回结果
def reinsertion(self, population, offspring, NUM, uniformPoint): """ 描述: 重插入个体产生新一代种群(采用父子合并选择的策略)。 NUM为所需要保留到下一代的个体数目。 """ # 父子两代合并 population = population + offspring # 选择个体保留到下一代 [levels, criLevel] = self.ndSort(population.ObjV, NUM, None, population.CV, self.problem.maxormins) # 对NUM个个体进行非支配分层 chooseFlag = ea.refselect(population.ObjV, levels, criLevel, NUM, uniformPoint, self.problem.maxormins) # 根据参考点的“入龛”个体筛选 return population[chooseFlag]
def calFitnV(self, population, NUM, uniformPoint): """ 描述: 计算种群个体的适应度 算法: 先对所需个体进行非支配排序分级,然后利用参考点关联选出所需要数量的点,最后结合帕累托分级以及是否被选择来计算适应度。 输出参数: FitnV : array - 种群个体的适应度列向量 """ [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NUM, None, population.CV) # 对NUM个个体进行非支配分层 chooseFlag = ea.refselect( self.problem.maxormins * population.ObjV, levels, criLevel, NUM, uniformPoint, True) # 根据参考点选择个体(True表示使用伪随机数方法,可以提高速度,详见refselect帮助文档) FitnV = np.array([1 / (levels - chooseFlag + 1)]).T # 计算适应度 return FitnV