最近的学习python,尝试了python实现粒子群算法的基本过程,定义了变量的上下界,利用pso 求解简单约束的问题,Spere 函数进行了检验。
感觉利用MATLAB的矩阵形式编写的pso 较快。
适应值函数通过对象的方式传递给pso class。
#-*- coding:utf-8 -*-
# 作者:gongxu
# 时间:20181111
# 基本的粒子群算法,能够解决约束问题,约束问题仅限上下边界。
import numpy as np
import matplotlib.pyplot as plt
class pso:
"""
w: 惯性系数
c1:学习因子1
c2:学习因子2
max_iter:最大迭代次数
var_num:变量的个数
bound:变量的边界
pop:种群的个数
fitness_fun:适应值函数
"""
def __init__(self,w,c1,c2,max_iter,var_num,bound,pop,fitness_fun):
self.w =w
self.c1 =c1
self.c2 =c2
self.max_iter=max_iter
self.var_num=var_num
self.bound=bound
self.pop=pop
self.fitness_fun=fitness_fun
self.best_fit=[]
self.fitness=np.zeros(pop)
self.positions=bound[1,:]+np.random.rand(pop,var_num)*(bound[0,:]-bound[1,:])
self.velecitys=0.1*self.positions.copy()
self.iter_fit=np.zeros(max_iter)
self.fitness=self.fitness_fun(self.positions)
self.best_fit=self.fitness.copy()
self.best_pos=self.positions.copy()
self.global_fit=np.min(self.fitness)
self.global_pos=self.positions[np.argmin(self.fitness)].copy()
def fly_finding(self):
self.velecitys=self.w*self.velecitys+self.c1*np.random.rand(self.pop,self.var_num)*(self.best_pos-self.positions) \
+self.c2*np.random.rand(self.pop,self.var_num)*(self.global_pos-self.positions)
for i in range(self.pop):
index_up=self.velecitys[i]>self.bound[0,:]
self.velecitys[i,index_up]=self.bound[0,index_up].copy()
index_down=self.velecitys[i]<self.bound[1,:]
self.velecitys[i,index_down]=self.bound[1,index_down].copy()
self.positions=self.positions.copy()+self.velecitys.copy()
for i in range(self.pop):
index_up=self.positions[i]>self.bound[0,:]
self.positions[i,index_up]=self.bound[0,index_up].copy()
index_down=self.positions[i]<self.bound[1,:]
self.positions[i,index_down]=self.bound[1,index_down].copy()
def update_position(self):
self.fitness=self.fitness_fun(self.positions)
index=self.fitness<self.best_fit
self.best_fit[index]=self.fitness[index].copy()
self.best_pos[index,:]=self.positions[index,:].copy()
self.global_fit=np.min(self.best_fit)
self.global_pos=self.best_pos[np.argmin(self.best_fit),:].copy()
def run(self):
for i in range(0,self.max_iter):
self.fly_finding()
self.update_position()
self.iter_fit[i]=self.global_fit.copy()
print('gloabal best fitness:',self.iter_fit[i],end='\n')
def show_result(self):
plt.plot(range(self.max_iter),self.iter_fit,'-b')
plt.title('converage of process in pso')
plt.xlabel('iter')
plt.ylabel('fitness')
plt.show()
def print_result(self):
print('the result is showing...')
print('best_fitness for min problem:',self.global_fit)
print('best solution for result:',self.global_pos)
def fitness_fun(x):
result=np.sum(x*x,axis=1)
return result
def main():
w=1
c1=2
c2=2
max_iter=1000
var_num=10
pop=50
bound=np.zeros((2,var_num))
bound[0,:]=np.ones(var_num)*10 #上边界,每个变量的上边界可以不同
bound[1,:]=-np.ones(var_num)*10 #下边界,每个变量的下边界可以不同
pso_new=pso(w,c1,c2,max_iter,var_num,bound,pop,fitness_fun)
pso_new.run()
pso_new.print_result()
pso_new.show_result()
if __name__=='__main__':
main()