上演化计算课的时候老师让我们实现EOPSO算法(一种精英反向的粒子群优化算法),下面是他的算法步骤:
首先我们需要知道一些基础知识:
(1)基础PSO算法
(2)精英反向解
import numpy as np import random import math class Population: def __init__(self,min_range_x,max_range_x,min_range_v,max_range_v,w,c1,c2,r1,r2,size,dim,rounds,f,CR,k,object_func): self.min_range_x = min_range_x self.max_range_x = max_range_x self.min_range_v = min_range_v self.max_range_v = max_range_v self.w = w self.c1 = c1 self.c2 = c2 self.r1 = r1 self.r2 = r2 self.size = size self.dimension = dim self.rounds = rounds self.f = f self.CR = CR self.k = k self.get_object_function_value = object_func self.cur_round = 0 #初始化粒子位置和速度,gbest,pbest,精英反向解 self.X = np.array([np.array([random.uniform(self.min_range_x, self.max_range_x) for s in range(self.dimension)]) for tmp in range(size)]) self.V = np.array([np.array([random.uniform(self.min_range_v, self.max_range_v) for s in range(self.dimension)]) for tmp in range(size)]) self.object_function_values = [self.get_object_function_value(v) for v in self.X] self.pbest = self.X.copy() self.gbest = self.X[np.argmin(self.object_function_values)] # self.opx = [np.array([self.k * (self.X[:,s].min() + self.X[:,s].max) - self.X[tmp][s] for s in range(self.dimension)]) # for tmp in range(size)] self.opx = np.zeros_like(self.X) self.m = np.zeros_like(self.gbest) #生成反向精英向量 def make_op(self): for i in range(self.size): for j in range(self.dimension): da=self.X[:,j].min() db=self.X[:,j].max() self.opx[i][j] = self.k*(da+db) - self.X[i][j] if self.opx[i][j] < self.min_range_x or self.opx[i][j] > self.max_range_x: self.opx[i][j] = random.uniform(self.min_range_x, self.max_range_x) #选择 def select(self): for i in range(self.size): x1 = self.X[i] x2 = self.opx[i] if self.get_object_function_value(x1) >= self.get_object_function_value(x2): self.pbest[i] = x2 else: self.pbest[i] = x1 if self.get_object_function_value(self.pbest[i]) <= self.get_object_function_value(self.gbest): self.gbest = self.pbest[i] # 变异 def mutate(self): for i in range(self.size): r0, r1, r2, r3 = 0, 0, 0, 0 while r0 == r1 or r1 == r2 or r2 == r3 or r0 == r3 or r0 == r2 or r1 == r3 or r0 == i: r0 = random.randint(0, self.size - 1) r1 = random.randint(0, self.size - 1) r2 = random.randint(0, self.size - 1) r3 = random.randint(0, self.size - 1) #变异向量 for j in range(self.dimension): self.m[j] = self.gbest[j] + self.f * (self.X[r0][j] - self.X[r1][j]) + self.f * (self.X[r2][j] - self.X[r3][j]) if self.m[j] > self.max_range_x or self.m[j] < self.min_range_x: self.m[j] = random.uniform(self.min_range_x, self.max_range_x) #交叉 def crossover(self): Jrand = random.randint(0, self.dimension) for j in range(self.dimension): if random.random() >= self.CR and j != Jrand: self.gbest[j] = self.m[j] #更新速度和位置 def updata(self): for i in range(self.size): for j in range(self.dimension): self.V[i][j] = self.w * self.V[i][j] + self.c1 * self.r1 * (self.pbest[i][j] - self.X[i][j]) + \ self.c2 * self.r2 * (self.gbest[j] - self.X[i][j]) self.X[i][j] = self.X[i][j] + self.V[i][j] def print_best(self): m = min(self.object_function_values) i = self.object_function_values.index(m) print("轮数:" + str(self.cur_round)) print("最佳个体:" + str(self.X[i])) print("目标函数值:" + str(m)) def evolution(self): JR = 0.3 while self.cur_round < self.rounds: if random.random() < JR: self.make_op() self.select() else: self.updata() self.mutate() self.crossover() self.print_best() self.cur_round = self.cur_round + 1 if __name__ == "__main__": def func(x): return x**2 p = Population(min_range_x=-3,max_range_x=3,min_range_v=-3,max_range_v=3,w=0.6,c1=1.193,c2=1.193, r1=random.random(),r2=random.random(),size=30,dim=1,rounds=100,f=1,CR=0.1,k=random.random() ,object_func=func) p.evolution()
标签:object,PSO,min,python,max,self,random,range,变体 From: https://www.cnblogs.com/lyansu/p/16926608.html