import numpy as np
import random
import matplotlib.pyplot as plt
import datetime
def fit_fun(x): # 适应函数
param1, param2, param3 = x[0], x[1], x[2]
# 自定义适应度函数
fit_fun = param1 + param2 + param3
return fit_fun
class Particle:
# 初始化
def __init__(self, x_max, max_vel, dim):
if len(x_max[0]) == 2:
self.__pos = [random.uniform(x_max[i][0], x_max[i][1]) for i in range(dim)] # 粒子的位置
else:
self.__pos = [x_max[i][0] for i in range(dim)]
self.__vel = [random.uniform(-max_vel[i], max_vel[i]) for i in range(dim)] # 粒子的速度
self.__bestPos = [0.0 for i in range(dim)] # 粒子最好的位置
self.__fitnessValue = fit_fun(self.__pos) # 适应度函数值
def set_pos(self, i, value):
self.__pos[i] = value
def get_pos(self):
return self.__pos
def set_best_pos(self, i, value):
self.__bestPos[i] = value
def get_best_pos(self):
return self.__bestPos
def set_vel(self, i, value):
self.__vel[i] = value
def get_vel(self):
return self.__vel
def set_fitness_value(self, value):
self.__fitnessValue = value
def get_fitness_value(self):
return self.__fitnessValue
class PSO:
def __init__(self, dim, size, iter_num, x_max_list, max_vel_list, best_fitness_value=float('Inf'), C1=2, C2=2, W=1):
self.C1 = C1
self.C2 = C2
self.W = W
self.dim = dim # 粒子的维度
self.size = size # 粒子个数
self.iter_num = iter_num # 迭代次数
self.x_max_list = x_max_list
self.max_vel_list = max_vel_list # 粒子最大速度
self.best_fitness_value = best_fitness_value
self.best_position = [0.0 for i in range(dim)] # 种群最优位置
self.fitness_val_list = [] # 每次迭代最优适应值
# 对种群进行初始化
self.Particle_list = [Particle(self.x_max_list, self.max_vel_list, self.dim) for i in range(self.size)]
pos = [[0.000002], [0.00061], [0.02], [-2.5]]
self.Particle_list.append(Particle(pos, self.max_vel_list, self.dim))
def set_bestFitnessValue(self, value):
self.best_fitness_value = value
def get_bestFitnessValue(self):
return self.best_fitness_value
def set_bestPosition(self, i, value):
self.best_position[i] = value
def get_bestPosition(self):
return self.best_position
# 更新速度
def update_vel(self, part):
for i in range(self.dim):
vel_value = self.W * part.get_vel()[i] + self.C1 * random.random() * (part.get_best_pos()[i] - part.get_pos()[i]) \
+ self.C2 * random.random() * (self.get_bestPosition()[i] - part.get_pos()[i])
if vel_value > self.max_vel_list[i]:
vel_value = self.max_vel_list[i]
elif vel_value < -self.max_vel_list[i]:
vel_value = -self.max_vel_list[i]
part.set_vel(i, vel_value)
# 更新位置
def update_pos(self, part):
for i in range(self.dim):
pos_value = part.get_pos()[i] + part.get_vel()[i]
# 添加逻辑,确保位置参数在设定的取值范围内
if pos_value > self.x_max_list[i][1]:
pos_value = self.x_max_list[i][1]
elif pos_value < self.x_max_list[i][0]:
pos_value = self.x_max_list[i][0]
part.set_pos(i, pos_value)
value = fit_fun(part.get_pos())
if value < part.get_fitness_value():
part.set_fitness_value(value)
for i in range(self.dim):
part.set_best_pos(i, part.get_pos()[i])
if value < self.get_bestFitnessValue():
self.set_bestFitnessValue(value)
for i in range(self.dim):
self.set_bestPosition(i, part.get_pos()[i])
def update(self):
for i in range(self.iter_num):
start_time = datetime.datetime.now()
for part in self.Particle_list:
self.update_vel(part) # 更新速度
self.update_pos(part) # 更新位置
self.fitness_val_list.append(self.get_bestFitnessValue()) # 每次迭代完把当前的最优适应度存到列表
end_time = datetime.datetime.now()
print('当前最好评估指标值:', float('{:.6f}'.format(self.get_bestFitnessValue())))
print('当前最好参数组的值:', [float('{:.6f}'.format(i)) for i in self.get_bestPosition()])
print ("执行第", i, "个迭代耗时(秒):", end_time - start_time)
return self.fitness_val_list, self.get_bestPosition()
size = 30
iter_num = 100
x_max = [[0, 0.00001], [0.0001,0.001], [0, 0.2], [-3, -2]]
dim = len(x_max)
max_vel = []
for i in range(dim):
max_vel.append((x_max[i][1] - x_max[i][0])* 0.1)
pso = PSO(dim, size, iter_num, x_max, max_vel)
fit_var_list1, best_pos1 = pso.update()
print("PSO最优位置:" + str(best_pos1))
print("PSO最优解:" + str(fit_var_list1[-1]))
plt.plot(np.linspace(0, iter_num, iter_num), fit_var_list1, c="R", alpha=0.5, label="PSO")
plt.legend() # 显示lebel
plt.show()
PSO实战
最新推荐文章于 2023-08-25 18:15:24 发布