Ejemplo n.º 1
0
 def aimFunc(self, pop):  # 目标函数
     centers = pop.Phen.reshape(int(pop.sizes * self.k),
                                int(pop.Phen.shape[1] / self.k))  # 得到聚类中心
     dis = ea.cdist(centers, self.datas, 'euclidean')  # 计算距离
     dis_split = dis.reshape(
         pop.sizes, self.k,
         self.datas.shape[0])  # 分割距离矩阵,把各个聚类中心到各个点之间的距离的数据分开
     labels = np.argmin(dis_split, 1)[0]  # 得到聚类标签值
     uni_labels = np.unique(labels)
     for i in range(len(uni_labels)):
         centers[uni_labels[i], :] = np.mean(
             self.datas[np.where(labels == uni_labels[i])[0], :], 0)
     # 直接修改染色体为已知的更优值,加快收敛
     pop.Chrom = centers.reshape(pop.sizes, self.k * centers.shape[1])
     pop.Phen = pop.decoding()  # 染色体解码(要同步修改Phen,否则后面会导致数据不一致)
     dis = ea.cdist(centers, self.datas, 'euclidean')
     dis_split = dis.reshape(pop.sizes, self.k, self.datas.shape[0])
     pop.ObjV = np.sum(np.min(dis_split, 1), 1, keepdims=True)  # 计算个体的目标函数值
Ejemplo n.º 2
0
 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完成后续工作并返回结果
Ejemplo n.º 3
0
 def renewRefPoint(self, ObjV, refPoint):  # 更新参考点
     _ObjV = ObjV - np.min(ObjV, 0)
     linkIdx = np.argmax(ea.cdist(_ObjV, refPoint, 'cosine_similarity'),
                         1)  # 找到与参考点关联的点的索引
     noLinkIdx = list(set(range(refPoint.shape[0])) -
                      set(linkIdx))  # 找到不与参考点关联的点的索引
     refPoint[noLinkIdx, :] = np.random.rand(
         len(noLinkIdx), refPoint.shape[1]) * np.max(_ObjV, 0)
     return refPoint
Ejemplo n.º 4
0
 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完成后续工作并返回结果
Ejemplo n.º 5
0
 def draw(self, centers):  # 绘制聚类效果图
     dis = ea.cdist(centers, self.datas, 'euclidean')
     dis_split = dis.reshape(1, self.k, self.datas.shape[0])
     labels = np.argmin(dis_split, 1)[0]
     colors = ['r', 'g', 'b', 'y']
     fig = plt.figure()
     ax = fig.add_subplot(111, projection='3d')
     for i in range(self.k):
         idx = np.where(labels == i)[0]  # 找到同一类的点的下标
         datas = self.datas[idx, :]
         ax.scatter(datas[:, 0], datas[:, 1], datas[:, 2], c=colors[i])
 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完成后续工作并返回结果