PSO-粒子群算法
介绍
嗯,算法作业,网上找的,然后我自己补充了注释,方便理解,仅用于学习和参考。
具体内容嘛,就是用粒子群算法解一个函数最值,太难的我也不会。
目标函数:
x 2 − 4 x + 3 x^{2}-4x+3 x2−4x+3
完整代码
# -*- coding: utf-8 -*-
import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D#导入该函数是为了绘制3D图
import matplotlib as mpl
import copy
# ----------------------PSO参数设置---------------------------------
class PSO():
def __init__(self, pN, dim, max_iter): #构造方法 初始参数设置
self.w = 0.8 #惯性权重
self.c1 = 2 #个体学习因子
self.c2 = 2 #群体学习因子
self.r1 = random.random() #区间[0,1]内的随机数,增加搜索的随机性
self.r2 = random.random() #区间[0,1]内的随机数,增加搜索的随机性
self.pN = pN #粒子数量
self.dim = dim #搜索维度
self.max_iter = max_iter #迭代次数
self.X = np.zeros((self.pN, self.dim)) #所有粒子的位置
self.V = np.zeros((self.pN, self.dim)) #所有粒子的速度
self.pbest = np.zeros((self.pN, self.dim)) #个体历史的最佳位置
self.gbest = np.zeros((1, self.dim)) #全局历史的最佳位置
self.p_fit = np.zeros(self.pN) # 每个个体的历史最佳适应值
self.fit = 1e10 # 全局最佳适应值
# ---------------------目标函数-----------------------------
def function(self, X):
return (X**2-4*X+3)
# ---------------------初始化种群----------------------------------
def init_Population(self):
#初始化粒子
for i in range(self.pN): #因为有pN个粒子,所以需要循环pN次,逐一初始化
#初始化位置与速度
for j in range(self.dim):#每一个维度都需要生成速度和位置,故循环dim次
self.X[i][j] = random.uniform(0, 1)
self.V[i][j] = random.uniform(0, 1)
#初始化个体最佳位置
self.pbest[i] = copy.copy(self.X[i])#其实就是给self.pbest定值
#初始化个体最佳适应值
tmp = self.function(self.X[i])#得到该粒子初始位置的适应值
self.p_fit[i] = tmp #初始时该粒子最佳的适应值
if tmp < self.fit: #将全局最佳适应值与该粒子此时适应值比较,若全局最佳适应值大于该粒子此时适应值,则更新全局最优(全局最佳适应值与全局历史的最佳位置都更新)
self.fit = tmp
self.gbest = copy.copy(self.X[i])
def iterator(self):
fitness = []
fig = plt.figure(figsize=(20,20))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('迭代次数')
ax.set_ylabel('位置')
ax.set_zlabel('最优值')
for t in range(self.max_iter): #迭代次数,不是越多越好
for i in range(self.pN): # 更新gbest\pbest
temp = self.function(self.X[i])
ax.scatter(t,self.X[i],temp)
if temp < self.p_fit[i]: # 更新个体最优 ()
self.pbest[i] = copy.copy(self.X[i])
self.p_fit[i] = copy.copy(temp)
if self.p_fit[i] < self.fit: # 更新全局最优
self.gbest = copy.copy(self.X[i])
self.fit = copy.copy(self.p_fit[i])
for i in range(self.pN):
#速度更新 公式V(t+1)=w*V(t)+c1*r1*(pbest_i-xi)+c1*r1*(gbest_xi)
self.V[i] = self.w * self.V[i] + self.c1 * self.r1 * (self.pbest[i] - self.X[i]) + self.c2 * self.r2 * (self.gbest - self.X[i])
#位置更新 公式X(t+1)=X(t)+V
self.X[i] = self.X[i] + self.V[i]
fitness.append(self.fit)
print(self.gbest, end=" ")
print(self.fit) # 输出最优值
plt.savefig('3D.png')
plt.show()
return fitness
# ----------------------程序执行-----------------------
#主函数
if __name__=="__main__":
my_pso = PSO(pN=40, dim=1, max_iter=100)
my_pso.init_Population()
fitness = my_pso.iterator()
# -------------------画图--------------------
plt.figure(1)
plt.title("Figure1")
plt.xlabel("iterators", size=14)
plt.ylabel("fitness", size=14)
t = np.array([t for t in range(0, 100)])
fitness = np.array(fitness)
plt.plot(t, fitness, color='b', linewidth=3)
plt.savefig('polt.png')
plt.show()