def reinsertion(self, population, offspring, NUM, globalNDSet): """ 描述: 重插入个体产生新一代种群(采用父子合并选择的策略)。 NUM为所需要保留到下一代的个体数目,globalNDSet为全局非支配解存档。 """ # 父子两代合并 population = population + offspring globalNDSet = population + globalNDSet # 将population与全局存档合并 # 非支配排序分层 [levels, criLevel] = self.ndSort(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: dis = ea.crowdis(globalNDSet.ObjV, np.ones(globalNDSet.sizes)) # 计算拥挤距离 globalNDSet = globalNDSet[np.argsort( -dis)[:self.MAXSIZE]] # 根据拥挤距离选择符合个数限制的解保留在存档中 # 选择个体保留到下一代 levels = levels[:population.sizes] # 得到与population个体对应的levels dis = ea.crowdis(population.ObjV, levels) # 计算拥挤距离 population.FitnV[:, 0] = np.argsort(np.lexsort(np.array([dis, -levels])), kind='mergesort') # 计算适应度 chooseFlag = ea.selecting('dup', population.FitnV, NUM) # 调用低级选择算子dup进行基于适应度排序的选择,保留NUM个个体 return population[chooseFlag], globalNDSet
def updateNDSet(population, maxormins, MAXSIZE, NDSet=None): """ 描述: 用于计算种群个体的适应度及更新全局非支配种群。 输入参数: population : Population - 种群对象。 maxormins : list - 优化目标的最大最小化标记列表。 MAXSIZE : int - 示全局非支配个体的最大数目。 NDSet : Population - (可选参数)全局非支配个体, 若缺省或为None时,NDSet为所传入种群的非支配个体组成的种群。 输出参数: NDSet : Population - (可选参数)全局非支配种群。 种群适应度FitnV已经在函数中进行更新,因此这该参数不用返回。 """ ObjV = maxormins * population.ObjV # 对目标进行统一最小化 [levels, criLevel] = ea.ndsortDED(ObjV, None, 1, population.CV) # 只对个体划分出第一层 [CombinObjV, weight] = ea.awGA(ObjV, population.CV) # 计算适应性权重以及多目标的加权单目标 population.FitnV = (np.max(CombinObjV) - CombinObjV + 0.5) / ( np.max(CombinObjV) - np.min(CombinObjV) + 0.5) # 计算种群适应度 # 更新NDSet if NDSet is None: return population[np.where(levels == 1)[0]] else: tempPop = population[np.where( levels == 1)[0]] + NDSet # 将种群可行个体与NDSet合并 [levels, criLevel] = ea.ndsortDED(maxormins * tempPop.ObjV, None, 1, tempPop.CV) # 只对个体划分出第一层 liveIdx = np.where(levels == 1)[0] # 选择非支配个体 NDSet = tempPop[liveIdx] # 对种群中被NDSet支配的个体进行惩罚 punishFlag = np.zeros(population.sizes) punishFlag[np.where(liveIdx < population.sizes)[0]] == 1 population.FitnV[np.where(punishFlag == 0)[0]] *= 0.5 if len(liveIdx) > MAXSIZE: # 若要保留下来的NDSet个体数大于MAXSIZE,则根据拥挤距离进行筛选 dis = ea.crowdis(NDSet.ObjV, levels[liveIdx]) # 计算拥挤距离 NDSet = NDSet[ea.selecting('dup', np.array([dis]).T, MAXSIZE)] # 进行筛选 return NDSet
def reinsertion(self, population, offspring, NUM): """ 描述: 重插入个体产生新一代种群(采用父子合并选择的策略)。 NUM为所需要保留到下一代的个体数目。 注:这里对原版NSGA-II进行等价的修改:先按帕累托分级和拥挤距离来计算出种群个体的适应度, 然后调用dup选择算子(详见help(ea.dup))来根据适应度从大到小的顺序选择出个体保留到下一代。 这跟原版NSGA-II的选择方法所得的结果是完全一样的。 """ # 父子两代合并 population = population + offspring # 选择个体保留到下一代 [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NUM, None, population.CV) # 对NUM个个体进行非支配分层 dis = ea.crowdis(population.ObjV, levels) # 计算拥挤距离 population.FitnV[:, 0] = np.argsort(np.lexsort(np.array([dis, -levels])), kind = 'mergesort') # 计算适应度 chooseFlag = ea.selecting('dup', population.FitnV, NUM) # 调用低级选择算子dup进行基于适应度排序的选择,保留NUM个个体 return population[chooseFlag]
def calFitnV(self, population, NUM): """ 描述: 计算种群个体的适应度 算法: 先对所需个体进行非支配排序分级,然后对所有个体进行拥挤度计算,最后先让处于较前帕累托分层的 个体得到较高的适应度,对于同一层,则让拥挤距离大的个体得到较高的适应度 输出参数: FitnV : array - 种群个体的适应度列向量 """ [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NUM, None, population.CV) # 对NUM个个体进行非支配分层 dis = ea.crowdis(population.ObjV, levels) # 计算拥挤距离 FitnV = np.array([ np.argsort(np.lexsort(np.array([dis, -levels])), kind='mergesort') ]).T # 计算适应度 return FitnV
def reinsertion(self, population, offspring, NUM): """ 描述: 重插入个体产生新一代种群(采用父子合并选择的策略)。 NUM为所需要保留到下一代的个体数目。 注:这里对原版NSGA-II进行等价的修改:先按帕累托分级和拥挤距离来计算出种群个体的适应度, 然后调用dup选择算子(详见help(ea.dup))来根据适应度从大到小的顺序选择出个体保留到下一代。 这跟原版NSGA-II的选择方法所得的结果是完全一样的。 """ # 父子两代合并 population = population + offspring # 选择个体保留到下一代 [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NUM, None, population.CV) # 对NUM个个体进行非支配分层 dis = ea.crowdis(population.ObjV, levels) # 计算拥挤距离 count = 0 cos_arr = np.zeros(dis.shape) # 计算余弦相似度 for i in population.ObjV: res = np.array([[ i[j] * self.target[j], i[j] * i[j], self.target[j] * self.target[j] ] for j in range(len(i))]) cos = sum(res[:, 0]) / (np.sqrt(sum(res[:, 1])) * np.sqrt(sum(res[:, 2]))) cos_arr[count] += cos count += 1 cos_arr = cos_arr * 0.8 dis = cos_arr + dis population.FitnV[:, 0] = np.argsort(np.lexsort(np.array([dis, -levels])), kind='mergesort') # 计算适应度 chooseFlag = ea.selecting('dup', population.FitnV, NUM) # 调用低级选择算子dup进行基于适应度排序的选择,保留NUM个个体 return population[chooseFlag]
def updateNDSet(self, population, globalNDSet=None): """ 描述: 更新globalNDSet。 """ if globalNDSet is None: globalNDSet = population else: globalNDSet = population + globalNDSet # 将population与全局归档集合并 if globalNDSet.CV is not None: # CV不为None说明有设置约束条件 globalNDSet = globalNDSet[np.where(np.all(globalNDSet.CV <= 0, 1))[0]] # 排除非可行解 if globalNDSet.sizes != 0: [levels, criLevel] = ea.ndsortDED(globalNDSet.ObjV, None, None, globalNDSet.CV, self.problem.maxormins) # 非支配排序 globalNDSet = globalNDSet[np.where(levels == 1)[0]] if globalNDSet.sizes > self.MAXSIZE: dis = ea.crowdis(globalNDSet.ObjV, np.ones(globalNDSet.sizes)) # 计算拥挤距离 globalNDSet = globalNDSet[np.argsort(-dis)[:self.MAXSIZE]] # 根据拥挤距离选择符合个数限制的解保留在存档中 return globalNDSet
def calFitnV(self, population, NUM): #输入population,NUM数 """ 描述: 计算种群个体的适应度 算法: 先对所需个体进行非支配排序分级,然后对所有个体进行拥挤度计算,最后先让处于较前帕累托分层的 个体得到较高的适应度,对于同一层,则让拥挤距离大的个体得到较高的适应度 输出参数: FitnV : array - 种群个体的适应度列向量 """ #ndSortESS函数中接收的变量为ObjV,目标函数,要乘以优化方向值//needNUM需要对多少个体进行分级//需要划分到多少层//CV约束矩阵 [levels, criLevel] = self.ndSort(self.problem.maxormins * population.ObjV, NUM, None, population.CV) # 对NUM个个体进行非支配分层 #返回levels:array行向量//代表种群个体的非支配排序分级,rank #criLevel表示临界层所在层数,加上本层后排序总数目超过了needNum dis = ea.crowdis(population.ObjV, levels) # 计算拥挤距离 FitnV = np.array([ np.argsort(np.lexsort(np.array([dis, -levels])), kind='mergesort') ]).T # 计算适应度 return FitnV