粒子群算法:
- PSO比较有潜力的应用领域有多目标优化,分类,模式识别,决策等
- PSO存在的问题:应当与其它算法结合,解决PSO易陷于局部最优的问题
粒子群“实体”:
粒子群算法流程:
粒子群更新:
速度更新公式:
位置更新公式:
线性递减权值:
wd=wstart-(wstart - wend)x (d/K)
d是当前迭代的次数,K是迭代总次数,wstart一般取0.9,wend一般取0.4
较大的w有较好的全局收敛能力,较小的w则有较强的局部收敛能力,因此,随着迭代次数的增加,惯性权重w应不断减少,从而使得粒子群算法在初期具有较强的全局收敛能力,而晚期具有较强的局部收敛能力
全部代码:
# -*- coding: utf-8 -*-
import math
import random
import numpy as np
import matplotlib.pyplot as plt
import pylab as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
class PSO:
def __init__(self, dim, time, size, low, up, v_low, v_high):
# 初始化
self.dim = dim # 变量个数
self.time = time # 迭代的代数
self.size = size # 种群大小
self.bound = [] # 变量的约束范围
self.bound.append(low)
self.bound.append(up)
self.v_low = v_low # 速度最小
self.v_high = v_high # 速度最大
self.x = np.zeros((self.size, self.dim)) # 所有粒子的位置
self.v = np.zeros((self.size, self.dim)) # 所有粒子的速度
self.p_best = np.zeros((self.size, self.dim)) # 每个粒子最优的位置
self.g_best = np.zeros((1, self.dim))[0] # 全局最优的位置
# 初始化第0代初始全局最优解
temp = -1000000
for i in range(self.size):
for j in range(self.dim):
self.x[i][j] = random.uniform(self.bound[0][j], self.bound[1][j]) # 随机初始化
self.v[i][j] = random.uniform(self.v_low, self.v_high)
# 更新
self.p_best[i] = self.x[i]
fit = self.fitness(self.p_best[i])
if fit > temp:
self.g_best = self.p_best[i]
temp = fit
def fitness(self, x):
"""
个体适应值计算
"""
y = 0
for i in range(dim-1):
y += 100*(x[i+1]-x[i]**2)**2 + (x[i]-1)**2
return y
def update(self, size):
""""
保证了全局一定小于局部
"""
c1 = 2.0 # 学习因子
c2 = 2.0
wstart = 0.9
wend = 0.4
for i in range(size):
# 更新速度(核心公式)
w = wstart - (wstart - wend) * (i+1) / self.time # 更新惯性权重
self.v[i] = w * self.v[i] + c1 * random.uniform(0, 1) * (
self.p_best[i] - self.x[i]) + c2 * random.uniform(0, 1) * (self.g_best - self.x[i])
# 速度限制
for j in range(self.dim):
if self.v[i][j] < self.v_low:
self.v[i][j] = self.v_low
if self.v[i][j] > self.v_high:
self.v[i][j] = self.v_high
# 更新位置
self.x[i] = self.x[i] + self.v[i]
# 位置限制
for j in range(self.dim):
if self.x[i][j] < self.bound[0][j]:
self.x[i][j] = self.bound[0][j]
if self.x[i][j] > self.bound[1][j]:
self.x[i][j] = self.bound[1][j]
# 更新p_best和g_best
if self.fitness(self.x[i]) < self.fitness(self.p_best[i]):
self.p_best[i] = self.x[i]
if self.fitness(self.x[i]) < self.fitness(self.g_best):
self.g_best = self.x[i]
def pso(self):
"""
输出全局最优
"""
best = []
self.final_best = np.array([1, 2, 3, 4])
# 迭代次数
for gen in range(self.time):
self.update(self.size)
# 全局最优值更新
if self.fitness(self.g_best) < self.fitness(self.final_best):
self.final_best = self.g_best.copy()
# 打印
print('当前最佳位置(全局最优):{}'.format(self.final_best))
temp = self.fitness(self.final_best)
print('当前的最佳适应度:{}'.format(temp))
best.append(temp)
# 画图
t = [i for i in range(self.time)]
plt.figure()
plt.plot(t, best, color='red', marker='.', ms=15)
plt.rcParams['axes.unicode_minus'] = False
plt.margins(0)
plt.xlabel(u"迭代次数") # X轴标签
plt.ylabel(u"适应度") # Y轴标签
plt.title(u"迭代过程") # 标题
plt.show()
if __name__ == '__main__':
time = 50
size = 100
dim = 4
v_low = -1
v_high = 1
low = [-30, -30, -30, -30]
up = [30, 30, 30, 30]
pso = PSO(dim, time, size, low, up, v_low, v_high)
pso.pso()
运行结果:
参考:https://blog.csdn.net/weixin_44580451/article/details/109503819?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161628781016780271552699%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161628781016780271552699&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-4-109503819.first_rank_v2_pc_rank_v29&utm_term=%E7%BA%BF%E6%80%A7%E9%80%92%E5%87%8FPSO
https://blog.csdn.net/Cyril_KI/article/details/108589078?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161624704016780269858599%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161624704016780269858599&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~hot_rank-4-108589078.first_rank_v2_pc_rank_v29&utm_term=PSO+python