def run(self, prophetPop = None): # prophetPop为先知种群(即包含先验知识的种群) #==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法模板的一些动态参数 #===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 population.initChrom(NIND) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 self.call_aimFunc(population) # 计算种群的目标函数值 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查,故应确保prophetPop是一个种群类且拥有合法的Chrom、ObjV、Phen等属性) if prophetPop is not None: population = (prophetPop + population)[:NIND] # 插入先知种群 # 确定邻域大小 if self.neighborSize is None: self.neighborSize = population.sizes self.neighborSize = max(self.neighborSize, 2) # 确保不小于2 # 生成由所有邻居索引组成的矩阵 neighborIdx = np.argsort(cdist(uniformPoint, uniformPoint), axis=1, kind='mergesort')[:, :self.neighborSize] # 计算理想点 idealPoint = ea.crtidp(population.ObjV, population.CV, self.problem.maxormins) # 创建全局存档 if self.MAXSIZE is None: self.MAXSIZE = 10 * population.sizes # 默认为10倍的种群个体数 [levels, criLevel] = ea.ndsortDED(population.ObjV, NIND, None, population.CV, self.problem.maxormins) # 对NIND个个体进行非支配分层 globalNDSet = population[np.where(levels == 1)[0]] # 创建全局存档,该全局存档贯穿进化始终,随着进化不断更新 if globalNDSet.CV is not None: # CV不为None说明有设置约束条件 globalNDSet = globalNDSet[np.where(np.all(globalNDSet.CV <= 0, 1))[0]] # 排除非可行解 #===========================开始进化============================ while self.terminated(population) == False: select_rands = np.random.rand(population.sizes) # 生成一组随机数 for i in range(population.sizes): indices = neighborIdx[i, :] # 得到邻居索引 if select_rands[i] < self.Ps: chooseIdx = indices[ea.rps(self.neighborSize, 2)] # 只从邻域中选择 else: chooseIdx = ea.rps(population.sizes, 2) matting_Chrom = population.Chrom[chooseIdx, :] # 选出2条来自被选个体的染色体 offspring = ea.Population(population.Encoding, population.Field, 1) # 实例化一个种群对象用于存储进化的后代(这里只进化生成一个后代) # 对选出的个体进行进化操作 offspring.Chrom = self.recOper.do(matting_Chrom) # 重组 offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 # 更新理想点 idealPoint = ea.crtidp(offspring.ObjV, offspring.CV, self.problem.maxormins, idealPoint) # 重插入更新种群个体 self.reinsertion(indices, population, offspring, idealPoint, uniformPoint) # 完成当代的进化后,更新全局存档 globalNDSet = population + globalNDSet # 将population与全局归档集合并 [levels, criLevel] = ea.ndsortDED(globalNDSet.ObjV, None, None, globalNDSet.CV, self.problem.maxormins) # 非支配排序 globalNDSet = globalNDSet[np.where(levels == 1)[0]] if globalNDSet.CV is not None: # CV不为None说明有设置约束条件 globalNDSet = globalNDSet[np.where(np.all(globalNDSet.CV <= 0, 1))[0]] # 排除非可行解 if globalNDSet.sizes > self.MAXSIZE: globalNDSet = globalNDSet[ea.rps(globalNDSet.sizes, self.MAXSIZE)] # 采用rps随机排列选择,控制全局存档的大小 self.passTime += time.time() - self.timeSlot # 更新用时记录 #=========================绘图及输出结果========================= if self.drawing != 0: ea.moeaplot(globalNDSet.ObjV, 'Pareto Front', saveFlag = True, gridFlag = True) # 返回帕累托最优集 return globalNDSet
def run(self, prophetPop=None): # prophetPop为先知种群(即包含先验知识的种群) # ==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法类的一些动态参数 # ===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 population.initChrom( NIND ) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查) if prophetPop is not None: population = (prophetPop + population)[:NIND] # 插入先知种群 self.call_aimFunc(population) # 计算种群的目标函数值 # 确定邻域大小 if self.neighborSize is None: self.neighborSize = population.sizes // 10 self.neighborSize = max(self.neighborSize, 2) # 确保不小于2 # 生成由所有邻居索引组成的矩阵 neighborIdx = np.argsort(ea.cdist(uniformPoint, uniformPoint), axis=1, kind='mergesort')[:, :self.neighborSize] neighborIdx_list = [] for i in range(population.sizes): neighborIdx_list.append(neighborIdx[i, :]) offspring = ea.Population(population.Encoding, population.Field, 1) # 实例化一个种群对象用于存储进化的后代(每一代只进化生成一个后代) # 计算理想点 idealPoint = ea.crtidp(population.ObjV, population.CV, self.problem.maxormins) # ===========================开始进化============================ while not self.terminated(population): select_rands = np.random.rand(population.sizes) # 生成一组随机数 Masks = np.random.rand(population.sizes, population.Lind) < self.Cr for i in range(population.sizes): if select_rands[i] < self.Ps: indices = neighborIdx_list[i] else: indices = np.arange(population.sizes) r = indices[ea.rps(len(indices), 2)] # 随机选择两个索引作为差分向量的索引 r1, r2 = r[0], r[1] # 得到差分向量索引 offspring.Chrom = population.Chrom[[i], :] Mask = Masks[i] offspring.Chrom[0][Mask] = offspring.Chrom[0][ Mask] + self.F * (population.Chrom[r1][Mask] - population.Chrom[r2][Mask]) offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 多项式变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 # 更新理想点 idealPoint = ea.crtidp(offspring.ObjV, offspring.CV, self.problem.maxormins, idealPoint) # 重插入更新种群个体 self.reinsertion(indices, population, offspring, idealPoint, uniformPoint) return self.finishing(population) # 调用finishing完成后续工作并返回结果
def run(self, prophetPop=None): # prophetPop为先知种群(即包含先验知识的种群) #==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法模板的一些动态参数 #===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 population.initChrom( NIND ) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 self.call_aimFunc(population) # 计算种群的目标函数值 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查,故应确保prophetPop是一个种群类且拥有合法的Chrom、ObjV、Phen等属性) if prophetPop is not None: population = (prophetPop + population)[:NIND] # 插入先知种群 # 确定邻域大小 if self.neighborSize is None: self.neighborSize = population.sizes // 10 self.neighborSize = max(self.neighborSize, 2) # 确保不小于2 # 生成由所有邻居索引组成的矩阵 neighborIdx = np.argsort(cdist(uniformPoint, uniformPoint), axis=1, kind='mergesort')[:, :self.neighborSize] # 计算理想点 idealPoint = ea.crtidp(population.ObjV, population.CV, self.problem.maxormins) #===========================开始进化============================ while self.terminated(population) == False: select_rands = np.random.rand(population.sizes) # 生成一组随机数 for i in range(population.sizes): if select_rands[i] < self.Ps: indices = neighborIdx[i, :] else: indices = np.arange(population.sizes) offspring = ea.Population(population.Encoding, population.Field, 1) # 实例化一个种群对象用于存储进化的后代(这里只进化生成一个后代) r = indices[ea.rps(len(indices), 2)] r1, r2 = r[[0]], r[[1]] # 得到差分向量索引 pop_Chrom = population.Chrom[[i], :] # 进行进化操作 offspring.Chrom = pop_Chrom + self.F * ( population.Chrom[r1, :] - population.Chrom[r2, :]) # 差分变异 offspring.Chrom = self.recOper.do( np.vstack([pop_Chrom, offspring.Chrom])) # 重组 offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 多项式变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 # 更新理想点 idealPoint = ea.crtidp(offspring.ObjV, offspring.CV, self.problem.maxormins, idealPoint) # 重插入更新种群个体 self.reinsertion(indices, population, offspring, idealPoint, uniformPoint) return self.finishing(population) # 调用finishing完成后续工作并返回结果
def run(self, prophetPop=None): # prophetPop为先知种群(即包含先验知识的种群) # ==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法类的一些动态参数 # ===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 population.initChrom( NIND ) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查) if prophetPop is not None: population = (prophetPop + population)[:NIND] # 插入先知种群 self.call_aimFunc(population) # 计算种群的目标函数值 # 确定邻域大小 if self.neighborSize is None: self.neighborSize = population.sizes self.neighborSize = max(self.neighborSize, 2) # 确保不小于2 # 生成由所有邻居索引组成的矩阵 neighborIdx = np.argsort(ea.cdist(uniformPoint, uniformPoint), axis=1, kind='mergesort')[:, :self.neighborSize] neighborIdx_list = [] for i in range(population.sizes): neighborIdx_list.append(neighborIdx[i, :]) offspring = ea.Population(population.Encoding, population.Field, 1) # 实例化一个种群对象用于存储进化的后代(每一代只进化生成一个后代) # 计算理想点 idealPoint = ea.crtidp(population.ObjV, population.CV, self.problem.maxormins) # ===========================开始进化============================ while not self.terminated(population): select_rands = np.random.rand(population.sizes) # 生成一组随机数 for i in range(population.sizes): indices = neighborIdx_list[i] # 得到邻居索引 if select_rands[i] < self.Ps: chooseIdx = indices[ea.rps(self.neighborSize, 2)] # 只从邻域中选择 else: chooseIdx = ea.rps(population.sizes, 2) matting_Chrom = population.Chrom[ chooseIdx, :] # 选出2条来自被选个体的染色体 # 对选出的个体进行进化操作 offspring.Chrom = self.recOper.do(matting_Chrom) # 重组 offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 # 更新理想点 idealPoint = ea.crtidp(offspring.ObjV, offspring.CV, self.problem.maxormins, idealPoint) # 重插入更新种群个体 self.reinsertion(indices, population, offspring, idealPoint, uniformPoint) return self.finishing(population) # 调用finishing完成后续工作并返回结果
def create_offspring(self, population, Xr0, select_rand, Mask, neighbor_index, idealPoint): """ 描述: 该函数用于产生子代个体以及更新理想点,它实际上是下面的主代码里抽取出来的, 若有理解困难,可以把该函数的代码重新放入主代码中。 """ if select_rand < self.Ps: indices = neighbor_index else: indices = np.arange(population.sizes) offspring = ea.Population(population.Encoding, population.Field, 1) # 实例化一个种群对象用于存储进化的后代(这里只进化生成一个后代) r = indices[ea.rps(len(indices), 2)] # 随机选择两个索引作为差分向量的索引 r1, r2 = r[0], r[1] # 得到差分向量索引 offspring.Chrom = Xr0 offspring.Chrom[0][Mask] = offspring.Chrom[0][Mask] + self.F * ( population.Chrom[r1][Mask] - population.Chrom[r2][Mask]) offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 多项式变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 # 更新理想点 idealPoint = ea.crtidp(offspring.ObjV, maxormins=self.problem.maxormins, old_idealPoint=idealPoint) return offspring, indices, idealPoint
def run(self, prophetPop=None): # prophetPop为先知种群(即包含先验知识的种群) # ==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法模板的一些动态参数 # ===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 population.initChrom(NIND) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 self.call_aimFunc(population) # 计算种群的目标函数值 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查,故应确保prophetPop是一个种群类且拥有合法的Chrom、ObjV、Phen等属性) if prophetPop is not None: population = (prophetPop + population)[:NIND] # 插入先知种群 # 确定邻域大小 if self.neighborSize is None: self.neighborSize = population.sizes self.neighborSize = max(self.neighborSize, 2) # 确保不小于2 # 生成由所有邻居索引组成的矩阵 neighborIdx = np.argsort(cdist(uniformPoint, uniformPoint), axis=1, kind='mergesort')[:, :self.neighborSize] # 计算理想点 idealPoint = ea.crtidp(population.ObjV, population.CV, self.problem.maxormins) # 创建全局存档 if self.MAXSIZE is None: self.MAXSIZE = 10 * population.sizes # 默认为10倍的种群个体数 globalNDSet = self.updateNDSet(population) # 创建全局存档,该全局存档贯穿进化始终,随着进化不断更新 # ===========================开始进化============================ while self.terminated(population) == False: select_rands = np.random.rand(population.sizes) # 生成一组随机数 for i in range(population.sizes): indices = neighborIdx[i, :] # 得到邻居索引 if select_rands[i] < self.Ps: chooseIdx = indices[ea.rps(self.neighborSize, 2)] # 只从邻域中选择 else: chooseIdx = ea.rps(population.sizes, 2) matting_Chrom = population.Chrom[chooseIdx, :] # 选出2条来自被选个体的染色体 offspring = ea.Population(population.Encoding, population.Field, 1) # 实例化一个种群对象用于存储进化的后代(这里只进化生成一个后代) # 对选出的个体进行进化操作 offspring.Chrom = self.recOper.do(matting_Chrom) # 重组 offspring.Chrom = self.mutOper.do(offspring.Encoding, offspring.Chrom, offspring.Field) # 变异 self.call_aimFunc(offspring) # 求进化后个体的目标函数值 # 更新理想点 idealPoint = ea.crtidp(offspring.ObjV, offspring.CV, self.problem.maxormins, idealPoint) # 重插入更新种群个体 self.reinsertion(indices, population, offspring, idealPoint, uniformPoint) # 完成当代的进化后,更新全局存档 globalNDSet = self.updateNDSet(population, globalNDSet) return self.finishing(population, globalNDSet) # 调用finishing完成后续工作并返回结果
def run(self, prophetPop=None): # prophetPop为先知种群(即包含先验知识的种群) # ==========================初始化配置=========================== population = self.population self.initialization() # 初始化算法类的一些动态参数 pushStage = True # 一开始是push stage rk = 1.0 # 论文中的rk,k的含义在论文中是代数,这里保留名称不作变化,下同 epsilon_k = 0 # 论文中的𝜀(k) epsilon_0 = 0 # 论文中的𝜀(0) idealPoints = [] # 存储历代的理想点的列表 nadirPoints = [] # 存储历代的反理想点的列表 delta = np.array([1e-6] * self.problem.M) # 论文中为了避免分母为0而设的delta self.Tc *= self.MAXGEN self.LastLGen = min(self.LastLGen, self.MAXGEN) # ===========================准备进化============================ uniformPoint, NIND = ea.crtup(self.problem.M, population.sizes) # 生成在单位目标维度上均匀分布的参考点集 population.initChrom(NIND) # 初始化种群染色体矩阵,此时种群规模将调整为uniformPoint点集的大小,initChrom函数会把种群规模给重置 # 插入先验知识(注意:这里不会对先知种群prophetPop的合法性进行检查) if prophetPop is not None: population = (prophetPop + population)[:NIND] # 插入先知种群 self.call_aimFunc(population) # 计算种群的目标函数值 # 确定邻域大小 if self.neighborSize is None: self.neighborSize = population.sizes // 10 self.neighborSize = max(self.neighborSize, 2) # 确保不小于2 # 生成由所有邻居索引组成的矩阵 neighborIdx = np.argsort(ea.cdist(uniformPoint, uniformPoint), axis=1, kind='mergesort')[:, :self.neighborSize] # 计算理想点 idealPoint = ea.crtidp(population.ObjV, maxormins=self.problem.maxormins) # 创建全局存档 globalNDSet = self.updateNDSet(population) # ===========================开始进化============================ while not self.terminated(population): idealPoints.append(idealPoint) nadirPoints.append(ea.crtidp(population.ObjV, maxormins=self.problem.maxormins, reverse=True)) # 更新epsilon_k if self.currentGen < self.Tc: # 更新rk if self.currentGen >= self.LastLGen: past_gen = self.currentGen - self.LastLGen rk = np.max( [np.abs((idealPoints[-1] - idealPoints[past_gen]) / np.max([idealPoints[past_gen], delta], 0)), np.abs((nadirPoints[-1] - nadirPoints[past_gen]) / np.max([nadirPoints[past_gen], delta], 0))]) violation, count = ea.mergecv( population.CV if population.CV is not None else np.zeros((population.sizes, 1)), return_count=True) if rk <= self.varient_epsilon and pushStage: epsilon_0 = np.max(violation) epsilon_k = epsilon_0 pushStage = False if not pushStage: rf = count / population.sizes if rf < self.alpha: epsilon_k *= (1 - self.tao) else: epsilon_k = (1 - self.currentGen / self.Tc) ** self.cp * epsilon_0 else: epsilon_k = 0 # 分开push stage和pull stage进行进化 select_rands = np.random.rand(population.sizes) Masks = np.random.rand(population.sizes, population.Lind) < self.Cr if pushStage: for i in range(population.sizes): # 产生后代 offspring, indices, idealPoint = self.create_offspring(population, population.Chrom[[i], :], select_rands[i], Masks[i], neighborIdx[i, :], idealPoint) # 重插入 self.push_stage_reinsertion(indices, population, offspring, idealPoint, uniformPoint) # 重插入更新种群个体 else: for i in range(population.sizes): # 产生后代 offspring, indices, idealPoint = self.create_offspring(population, population.Chrom[[i], :], select_rands[i], Masks[i], neighborIdx[i, :], idealPoint) # 重插入 self.pull_stage_reinsertion(indices, population, offspring, idealPoint, uniformPoint, epsilon_k) # 完成当代的进化后,更新全局存档 globalNDSet = self.updateNDSet(population, globalNDSet) return self.finishing(population, globalNDSet) # 调用finishing完成后续工作并返回结果