参考:
https://blog.csdn.net/m0_38097087/article/details/79818348
http://yarpiz.com/59/ypea121-mopso
Coello C A C , Pulido G T , Lechuga M S . Handling multiple objectives with particle swarm optimization[J]. IEEE Transactions on Evolutionary Computation, 2004, 8(3):256-279.。
是按照上面的第三个的那篇论文实习实现的
论文里面的速度更新公式没有用到惯性c,好像是因为他有个变异算子(还没实现)。
算法流程
- 初始化群体粒子群的位置和速度,计算适应值
- 评价粒子的适应度和Pareto支配关系
- 将非劣解保存到Archive中去
- 计算Archive集中的拥挤度,为粒子选择gbest
- 更新粒子的速度、位置、适应度、pbest
- 更新Archive
- 满足结束条件,则结束;否则,转到第4步继续循环。
import numpy as np
class Partical:
#每次都是对一个粒子进行操作
def __init__(self,x_min,x_max,max_v,min_v,fitness):
self.dim=len(x_min) #获得变量数
self.max_v=max_v
self.min_v=min_v
self.x_min=x_min
self.x_max=x_max
self.dominated=False #表示是否被支配
self.pos=np.zeros(self.dim)
self.pbest=np.zeros(self.dim)
self.initPos(x_min,x_max)#初始化粒子坐标&pbest
self._v=np.zeros(self.dim)
self.fitness=fitness
self.cur_fitness=fitness(self.pos)#当前的适应度
self.bestFitness=fitness(self.pos)#初始化pbest
def _updateFit(self):
if isDominates(np.array(self.cur_fitness),np.array(self.bestFitness)):
self.bestFitness=self.cur_fitness
self.pbest=self.pos
elif isDominates(np.array(self.bestFitness),np.array(self.cur_fitness)):
pass
else:
#互不支配随机选择一个
if np.random.random()<0.5:
self.bestFitness=self.cur_fitness
self.pbest=self.pos
def _updatePos(self):
self.pos=self.pos+self._v
for i in range(self.dim):
self.pos[i]=min(self.pos[i],self.x_max[i])
self.pos[i]=max(self.pos[i],self.x_min[i])
def _updateV(self,w,c1,c2,gbest):
'''这里进行的都是数组的运算'''
self._v=w*self._v+c1*np.random.random()*(self.pbest-self.pos)+c2*np.random.random()*(gbest-self.pos)
for i in range(self.dim):
self._v[i]=min(self._v[i],self.max_v[i])
self._v[i]=max