粒子群优化算法python

粒子群优化算法

一群鸟在随机搜索食物,在这个区域里只有一块食物。所有的鸟都不知道食物在那里。但是它们知道当前的位置离食物还有多远。那么,找到食物的最简单有效的方法就是搜寻离食物最近的鸟的周围区域。如果将鸟抽象为没有体积和质量的“粒子”,相当于问题的一个解,鸟群就相当于一个解集,离食物最近的鸟相当于解群中的最优粒子,食物的位置相当于全局最优解。

基本原理

粒子群算法是由 Kennedy 和 Eberhart 等通过模拟鸟群的觅食行为而提出的一种基于群体协作的随机搜索算法。标准粒子群算法搜索寻优的基本框架如图 所示:
在这里插入图片描述
每个粒子具有两个属性:
粒子位置 x
粒子速度 v
假设在一个 D 维的目标搜索空间中,有 N 个粒子组成一个群落。则:
第 i 粒子的位置为一个 D 维向量,表示为:
在这里插入图片描述

第 i 个粒子的飞行速度也是一个 D 维向量,表示为:
在这里插入图片描述

第 i 个粒子迄今为止搜索到的最优位置为个体极值,表示为:
在这里插入图片描述

整个粒子群迄今为止搜索到的最优位置为全局极值,表示为:
在这里插入图片描述
每个粒子追随当前的最优粒子在解空间中运动,并根据如下公式来更新自己的速度和位置:
速度变换公式:
在这里插入图片描述
位置变换公式为:
在这里插入图片描述

其中,w 为惯性权值;c1 和 c2 为学习因子,分别反映粒子的自我学习能力和向群体 最 优 粒 子学 习 的 能 力 ; r1 和 r2 为 [0,1] 的 均 匀 随 机数 ;vi为 粒 子 速 度,vi属于[-vmax,vmax],vmax是用户设定的一个常量,用来限制粒子的速度。
公式中,第一部分是粒子先前的速度与惯性权值的积,用来保证算法的全局
收敛性,第二部分是粒子自身的学习能力,第三部分是粒子的社会学习能力,表示粒子之间的信息共享与相互协作,第二、三部分是引起粒子速度变化的社会因素,使其在最优解附近具有局部搜索的能力。

算法步骤

基于上述流程,标准粒子群算法的具体步骤可描述如下:
步骤 1:在可行域中随机初始化一群粒子,包括粒子的规模 N、位置 xi和速
度 vi;
步骤 2:根据目标函数计算每个粒子的适应度值 Fit[i] ;
步骤 3:比较每个粒子的适应度值Fit[i]与个体极值 Pbest[i],若Fit[i] > Pbest[i],
则用 Fit[i] 替换 Pbest[i];
步骤 4:比较每个粒子的适应度值 [i]itF 与当前的全局极值 gbest[i],若
Fit[i] > gbest[i],则用 Fit[i] 替换 gbest[i];
步骤 5:根据公式(2-1),(2-2)更新粒子的速度 vi 和位置 xi ;
步骤 6:判断是否达到停止准则,如果达到设置的搜索精度或达到最大迭代次
数则退出,否则返回步骤 2。

代码实现

# coding: utf-8
import numpy as np
import random
import matplotlib.pyplot as plt
 

class PSO():
	# PSO参数设置
    def __init__(self, pN, dim, max_iter):
        self.w = 0.8
        self.c1 = 2
        self.c2 = 2
        self.r1 = 0.6
        self.r2 = 0.3
        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  # 全局最佳适应值
 
    #目标函数Sphere函数
    def function(self, X):
        return X**4-2*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] = 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 = self.X[i]
 
    # 更新粒子位置
    def iterator(self):
        fitness = []
        for t in range(self.max_iter):    #迭代次数,不是越多越好
            for i in range(self.pN):  # 更新gbest\pbest
                temp = self.function(self.X[i])
                if temp < self.p_fit[i]:  # 更新个体最优
                    self.p_fit[i] = temp
                    self.pbest[i] = self.X[i]
                    if self.p_fit[i] < self.fit:  # 更新全局最优
                        self.gbest = self.X[i]
                        self.fit = self.p_fit[i]
            for i in range(self.pN):
                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])
                self.X[i] = self.X[i] + self.V[i]
            fitness.append(self.fit)
            print(self.X[0], end=" ")
            print(self.fit)  # 输出最优值
        return fitness



##输出

#程序
my_pso = PSO(pN=30, 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.show()

在上面我们计算 适应度函数
我们看一看结果:
1.迭代图像
在这里插入图片描述

  • 8
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值