粒子群算法还是很有意思的
描述
粒子群优化算法(PSO) 是由James Kennedy (肯尼迪)博士和R.C. Eberhart 博士于1995 年提出的。该算法源于对鸟群、鱼群觅食行为的模拟。
在PSO 中,首先初始化一群随机粒子(随机解),然后通过迭代寻找最优解。
在每一次迭代中,粒子通过跟踪两个极值来更新自己的速度和位置
粒子跟踪的两个极值
第一个就是粒子本身所找到的最优解,这个解叫做个体极值;
另一个极值是整个种群目前找到的最优解,这个极值是全局极值;
另外也可以不用整个种群而只是用其中一部分作为粒子的邻居,那么在该邻居中的极值就是局部极值。
PSO 算法简单易实现,不需要调整很多参数,主要应用有神经网络的训练、函数的优化等。
粒子群优化算法是基于群体的演化算法, 其思想来源于人工生命和演化计算理论。Reynolds 对鸟群飞行的研究发现, 鸟仅仅是追踪它有限数量的邻居, 但最终的整体结果是整个鸟群好像在一个中心的控制之下, 即复杂的全局行为是由简单规则的相互作用引起的。
PSO 即源于对鸟群捕食行为的研究, 一群鸟在随机搜寻食物时, 如果这个区域里只有一块食物, 那么找到食物的最简单有效的策略就是搜寻目前离食物最近的鸟的周围区域。
部分代码
这里使用一个类来描述粒子群,每个粒子个体我们看作是这个类的一个实例,
并且通过把位置信息当作一个list,速度也当作一个list,算法本身即可支持任意维度的计算。从1-max,收敛效果也还不错,其中使用了7个多目标测试函数。
后续将继续进行PSO算法的改进。
完整代码见git:sunxueliang96/Machine-learning-stuffs/tree/master/计算智能相关算法
class Swarm:
def __init__(self):
self.pos = [] #个体位置
self.speed = []#个体速度
self.fitness = 0 #当前适应值
self.best_fitness = 0 #个体最优值
self.best_pos = []#个体最优解
for i in range(m):
self.pos.append(np.random.uniform(-rang, rang))
for i in range(m):
#self.speed.append(np.random.uniform(-1,1)*rang/100)#随机初始速度
self.speed.append(0)#初始速度为0
self.fitness = cal_fitness(self.pos)
self.best_fitness = self.fitness
self.best_pos = list.copy(self.pos)
def info(self):
print('pos',self.pos)
print('speed',self.speed)
print('fitness',self.fitness)
print('best_pos',self.best_pos)
def refresh_memory(self): #每次个体更新适应度及全局最优适应度。
global swarm_best_fitness,swarm_bset_id,swarm_best_pos
self.fitness = cal_fitness(self.pos)
if(self.fitness<self.best_fitness): #比个体极值好,则更新记忆
self.best_fitness = self.fitness
self.best_pos = list.copy(self.pos)
if(self.fitness<swarm_best_fitness):
swarm_best_fitness = self.fitness
swarm_best_pos = list.copy(self.pos)
def refresh_pos(self):#跟新个体自己的速度和位置
for i in range(m):
self.speed[i] = self.speed[i] + c1*np.random.uniform() * (self.best_pos[i]-self.pos[i]) + c2*np.random.uniform()*(swarm_best_pos[i]-self.pos[i])
next_pos = self.pos[i] + self.speed[i]
if (-rang<next_pos and next_pos<rang):
self.pos[i] = next_pos
else:
#print('out of range')
pass
更新位置和速度比较简单,根据公式即可
def update_swarm_best():#找到全局最好的粒子,更新全局最优解和全局极值,写成函数方便切换最大最小
global swarm_best_fitness,swarm_bset_id,swarm_best_pos
for i in range(n):
if(swarm[i].best_fitness<swarm_best_fitness):
#print('update at ',i,'best_fitness==',swarm_best_fitness)
swarm_best_fitness = swarm[i].best_fitness
swarm_best_pos = list.copy(swarm[i].best_pos)
swarm_bset_id = i