以下是笔者调试好的面向对象的PSO算法,已封装好,相关参数在主函数__main__下修改即可。
注:很多同学觉得面向对象很难,其实很简单,网上找几个实例运行看看就能懂了。其中self就是一个初始化自己的过程,相当于一个容器,你告诉机器要放入哪些参数和函数,这些参数和函数叫什么名字。
以下设置可行域为[-10,10],维度为5维,目标函数为
显然,我们最优解为[0,0,0,0,0]
以下为求解该问题的python程序
import numpy as np
def y(x):
return np.sum(x**2)
class PSO:
def __init__(self,y,num_iter,num_particles,num_dimensions,c1,c2,w,bound_low,bound_high,vel_low,vel_high):
self.fitness_function=y
self.num_iter=num_iter
self.num_particles=num_particles
self.num_dimensions=num_dimensions
self.c1=c1
self.c2=c2
self.w=w
self.vel_low=vel_low
self.vel_high=vel_high
self.bound_low=bound_low
self.bound_high=bound_high
# 粒子初始化
self.pos=np.random.uniform(bound_low,bound_high,(num_particles,num_dimensions))
self.vel=np.random.uniform(vel_high,vel_high,(num_particles,num_dimensions))
self.pbest_pos=self.pos.copy()
self.pnow_val=np.zeros(num_particles)
self.pbest_val=np.full(num_particles,np.inf)
self.gbest_pos=np.zeros((1,num_dimensions))
self.gbest_val=np.inf
# 边界速度限制处理
def limit_eachiter(self):
self.pos[self.pos>self.bound_high]=self.bound_high
self.pos[self.pos<self.bound_low]=self.bound_low
self.vel[self.vel>self.vel_high]=self.vel_high
self.vel[self.vel<self.vel_low]=self.vel_low
# 计算适应度、更新最优记录
def fitness_eachiter(self):
for i in range(self.num_particles):
self.pnow_val[i]=self.fitness_function(self.pos[i])
if self.pnow_val[i]<self.pbest_val[i]:
self.pbest_val[i]=self.pnow_val[i].copy()
self.pbest_pos[i]=self.pos[i].copy()
if self.pnow_val[i]<self.gbest_val:
self.gbest_val=self.pnow_val[i].copy()
self.gbest_pos=self.pos[i].copy()
# 粒子速度、位置更新,运用广播机制
def update_eachiter(self):
self.vel=self.w*self.vel+self.c1*np.random.rand()*(self.pbest_pos-self.pos)+\
self.c2*np.random.rand()*(self.gbest_pos-self.pos)
self.pos=self.pos+self.vel
# 主程序
def pso(self):
for i in range(self.num_iter):
self.limit_eachiter()
self.fitness_eachiter()
self.update_eachiter()
if __name__=='__main__':
num_iter=600
num_particles=50
num_dimensions=5
c1=2
c2=2
w=0.8
bound_low=-10
bound_high=10
vel_low=-1
vel_high=1
PSO=PSO(y,num_iter,num_particles,num_dimensions,c1,c2,w,bound_low,bound_high,vel_low,vel_high)
PSO.pso()
print('Optimal solution: x = {}, f(x) = {}'.format(PSO.gbest_pos, PSO.gbest_val))
运行一下,结果为:
Optimal solution: x = [-1.17921320e-10 -6.00967243e-11 6.29614150e-11 3.05093263e-10
-4.88228938e-11], f(x) = 1.1694676763834684e-19
完美!