天天看點

粒子群(PSO)算法的實作

粒子群算法還是很有意思的

描述

粒子群優化算法(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
           

更新位置和速度比較簡單,根據公式即可

粒子群(PSO)算法的實作
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
           

部分截圖

粒子群(PSO)算法的實作
Rosenbrock函數
粒子群(PSO)算法的實作
粒子群(PSO)算法的實作
Griewank函數
粒子群(PSO)算法的實作
Schaffer’s F7
粒子群(PSO)算法的實作
粒子群(PSO)算法的實作

繼續閱讀