Python实现粒子群算法
前言
由于粒子群算法原理简单,故这里不对算法原理做讲解,请自行搜索相关资料。
一、实现粒子群算法
import numpy as np
class Pso:
def __init__(self,fx,n_dim,c,low,high,target="MAX",w=0.8,pop=20,max_iter=1000): #接受传入的参数
self.max_iter=max_iter #迭代次数
self.n_dim=n_dim # X数据维度
self.pop=pop #种群个数
self.w=w #速度因子
self.c=c #局部优化因子
self.low=low #最小值
self.high=high #最大值
self.target = target
self.fx = fx
def cal_y(self,X): #计算传入的目标函数
Y = X[:,0].copy()
for index,i in enumerate(X):
target = self.fx(i)
Y[index] = target
return Y
def target_request(self,y): #如果要求目标函数最大值,则返回y最大的一行的索引;反之返回最小的
if self.target == "MAX":
return np.argmax(y)
else:
return np.argmin(y)
def start(self):
high = self.high
low = self.low
r = np.random.rand(self.n_dim)
X = np.random.uniform(low=self.low, high=self.high, size=(self.pop, self.n_dim)) #初始化X
V = np.random.uniform(low=self.low, high=self.high, size=(self.pop, self.n_dim)) #初始化V
Y = self.cal_y(X)
best_index = self.target_request(Y)
best = X[best_index,:] #全局最优
pbest_x = X.copy() #初始化局部最优
pbest_y = Y.copy() #初始化局部最优
gbest_x = best
gbest_y = Y[self.target_request(Y)] #初始化全局最优
for iter_num in range(self.max_iter): #开始迭代
for idv in range(self.pop): #遍历每一个粒子
x = X[idv,:]
v = V[idv,:]
for index in range(self.n_dim): #更新速度
v[index] = self.w*v[index]+self.c[index]*r[index]*(pbest_x[idv][index]-x[index])+self.c[index]*r[index]*(gbest_x[index]-x[index])
x+=v #更新位置
for i in range(self.n_dim): #防止越界情况出现
if x[i] > high:
x[i] = high
elif x[i] < low:
x[i] = low
y = self.cal_y(X)
for i in range(len(y)):
if self.target == "MAX": #区分开求目标函数最大值还是最小值
if y[i] > pbest_y[i]:
pbest_y[i] = y[i] #更新局部速度和局部位置
pbest_x[i] = X[i,:]
else:
pass
else:
if y[i] < pbest_y[i]:
pbest_y[i] = y[i]
pbest_x[i] = X[i,:]
else:
pass
gbest_y = y[self.target_request(y)] #更新全局速度和全局位置
gbest_x = X[self.target_request(y),:]
return gbest_x,gbest_y
二、使用自定义的类
def aim(p):
'''这里的p是numpy类型,由传入的参数n_dim决定维度。
在该函数中你需要构建你的问题
'''
return target
例:
def target(p): #待传入的目标函数
x1,x2 = p
y = x1**2+x2**2
return y
该例求出了f(x)=x1**2+x2* *2的最优值。你还可以用该算法来优化机器学习算法的参数,甚至也可以进行特征选择。
a = Pso(fx=target,n_dim=2,c=[0.5,0.5],low=-10,high=10,target="MIN",max_iter=1000)
x,y = a.start()
print("x:{} y:{}".format(x,y))
fx代表自定义的问题
最后实例化一个类,传入你想要得到的参数即可。
c代表着自我认识和社会认识的值
low代表下限,high代表上限
target代表该算法的优化方向
pop(粒子数)和w(速度因子)被赋予了默认值,也可以进行自定义修改。