粒子群优化算法——用PSO算法求解函数,最优解(0,0,...,0),Min=0

问题提出

使用PSO算法求解以下公式,最优解(0,0,…,0),Min=0
min ⁡ f ( x 1 , x 2 , … . x n ) = 10 ⋅ n + ∑ i = 1 n ( x i 2 − 10 ⋅ cos ⁡ ( 2 π x i ) ) . − 5.12 ≤ x i ≤ 5.12 \begin{array}{l} \min f\left(x_{1}, x_{2}, \ldots . x_{n}\right)=10 \cdot n+\sum_{i=1}^{n}\left(x_{i}^{2}-10 \cdot \cos \left(2 \pi x_{i}\right)\right) . \\ -5.12 \leq x_{i} \leq 5.12 \end{array} minf(x1,x2,.xn)=10n+i=1n(xi210cos(2πxi)).5.12xi5.12

粒子群优化算法

思想来源

粒子群优化算法(Particle Swarm Optimization,PSO)作为进化计算的一个分支,在1995年由Eberhart和Kennedy提出的一种全局搜索算法,同时他也是一种模拟自然界的生物活动以及群体智能的随机搜索算法。粒子群优化算法不仅从人工生命、鱼群、鸟群、群理论中汲取思想精华,还与遗传算法等具有进化算法的特点和搜索优化能力。

基本原理

鸟群在捕食过程中,通过各自的搜索与群体的合作最终找到食物的位置。每个小鸟在搜寻食物时会不断记录和更新它曾经到达的离食物最近的位置,同时通过信息交流比较每只鸟所找的最好位置,可以得出当前群体内的最好位置,有了指导方向后,根据群体经验,最终小鸟群体聚集到食物位置。
在粒子群优化算法中,鸟群的每个小鸟个体被称作一个“粒子”,通过随机产生一定规模的粒子最为问题搜索空间的有效解,然后进行迭代搜索,得到优化结果。类比小鸟,每个粒子都具有速度与位置,可以由问题定义的适应度函数确定粒子的适应值,然后不断进行迭代,由粒子本身的历史最优解和群体的全局最优解来影响粒子的速度与方向,让粒子在搜索空间中探索开发从而得到全局最优解。

鸟群觅食 粒子群优化算法
鸟群 搜索空间的一组有效解
觅食空间 问题的搜索空间
飞行速度 解的速度向量V
所在位置 解的位置向量X
个体认知与群体写作 各个粒子i根据信息更新位置
找到食物 找到全局最优解

基本流程

PSO流程图如下所示
粒子群优化算法——用PSO算法求解函数,最优解(0,0,...,0),Min=0_第1张图片

问题解决

Step 1

这里我们取n=2,便于初学者理解

函数可变形为:
f ( x , y ) = 10 × 2 + x 2 − 10 cos ⁡ ( 2 π x ) + y 2 − 10 cos ⁡ ( 2 π y ) f(x, y)=10 \times 2+x^{2}-10 \cos (2 \pi x)+y^{2}-10 \cos (2 \pi y) f(x,y)=10×2+x210cos(2πx)+y210cos(2πy)
其中 x,y属于[-5.12,5.12]

通过python绘出函数在在区间中的样式

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

# 生成x和y的数据
X=np.arange(-5.12,5.12,0.1)
Y=np.arange(-5.12,5.12,0.1)
X,Y=np.meshgrid(X,Y)
pi=np.pi

Z=20+X**2-10*np.cos(2*pi*X)+Y**2-10*np.cos(2*pi*Y)

#绘图
fig=plt.figure()
ax=Axes3D(fig)
surf=ax.plot_surface(X,Y,Z,cmap=cm.coolwarm)
plt.show()

结果:
粒子群优化算法——用PSO算法求解函数,最优解(0,0,...,0),Min=0_第2张图片
极小值点从图中可以看出有非常多个,最小值点不易找出。

Step 2

构造粒子群优化算法中的适应度函数fitnessfction()、速度更新函数velupdate()、位置更新函数pstionupdate()

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

# 指定默认字体
mpl.rcParams['font.sans-serif'] = ['SimHei']
# 解决保存图像中‘-’显示为方块的的问题
mpl.rcParams['axes.unicode_minus'] = False

# 计算粒子的适应度值,也就是目标函数值,X的维度是size*2
def fitnessfction(X):
    A = 10
    pi = np.pi
    x = X[:, 0]
    y = X[:, 1]

    return 20 + x ** 2 - 10 * np.cos(2 * pi * x) + y ** 2 - 10 * np.cos(2 * pi * y)

"""
根据速度更新公式更新每个粒子的速度
#种群大小20
:param V:粒子当前的速度矩阵,20*2的矩阵
:param X:粒子当前的位置矩阵,20*2的矩阵
:param ibest:每个粒子历史最优位置,20*2的矩阵
:param gbest:种群历史最优位置,1*2矩阵
"""


def velupdate(V, X, ibest, gbest, c1, c2, w, max_val):
    # 种群大小
    size = X.shape[0]
    # 生成size个0-1之间的随机数
    r1 = np.random.random((size, 1))
    r2 = np.random.random((size, 1))
    # 对照公式写
    V = w * V + c1 * r1 * (ibest - X) + c2 * r2 * (gbest - X)
    # 防越界处理
    V[V < -max_val] = -max_val
    V[V > max_val] = max_val
    return V

"""
根据公式更新粒子位置
:param X:粒子当前的位置矩阵,20*2的矩阵
:param V:粒子当前的速度矩阵,20*2的矩阵
"""


def pstionupdate(X, V):
    return X + V

Step 3

构造函数并实现PSO算法,其中,需要定义惯性因子、学习因子、维度等参数;之后使用循环语句进行迭代,迭代过程中,更新个体最优与群体最优解,即局部与全局的最优解,当迭代次数完成时,输出结果。

import matplotlib.pyplot as plt
import numpy as np
from psoset import fitnessfction, velupdate, pstionupdate


def pso():
    # PSO的参数
    # 惯性因子,一般取1
    w = 1
    # 学习因子,一般取2
    c1 = 2
    c2 = 2
    # 为两个(0,1)之间的随机数
    r1 = None
    r2 = None
    # 维度
    dim = 2
    # 种群大小
    size = 20
    # 算法最大迭代次数
    iter_num = 1000
    # 限制粒子最大速度为0.5
    max_val = 0.5
    # 初始的适应度,在迭代过程中不断减小这个值
    best_fitness = float(9e10)
    # 记录每次迭代过程中的种群适应度值变化
    fitness_value_list = []
    # 初始化种群的各个粒子位置
    # 用一个20*2的矩阵表示种群,每行表示一个粒子
    # 2维,表示x,y
    X = np.random.uniform(-5.12, 5.12, size=(size, dim))
    # 初始化种群的各个粒子的速度
    # 2维,表示x,y速度
    V = np.random.uniform(-0.5, 0.5, size=(size, dim))
    # 计算种群各个粒子的初始适应度
    ifitness = fitnessfction(X)
    # 计算种群的初始最优适应度值
    grpfitness = ifitness.min()
    # 添加到记录中
    fitness_value_list.append(grpfitness)
    # 初始的个体最优位置和种群最优位置
    ibest = X
    gbest = X[ifitness.argmin()]
    # 下来进行迭代
    for i in range(1, iter_num):
        # 更新速度
        V = velupdate(V, X, ibest, gbest, c1, c2, w, max_val)
        # 更新位置
        X = pstionupdate(X, V)
        # 计算各个粒子适应度
        ifitness2 = fitnessfction(X)
        # 计算群体最优适应度
        grpfitness2 = ifitness2.min()
        # 更新每个粒子的历史最优位置
        for j in range(size):
            if ifitness[j] > ifitness2[j]:
                ibest[j] = X[j]
                ifitness[j] = ifitness2[j]
        # 更新群体最优位置
        if grpfitness > grpfitness2:
            gbest = X[ifitness2.argmin()]
            grpfitness = grpfitness2
        # 记录迭代最优结果
        fitness_value_list.append(grpfitness)
        # 迭代次数+1
        i += 1

    # 打印迭代结果
    print("最优值是:%.5f" % fitness_value_list[-1])
    print("最优解是:x=%.5f,y=%.5f" % (gbest[0], gbest[1]))

    # 绘图
    plt.plot(fitness_value_list, color='r')
    plt.title('迭代过程')
    plt.show()


pso()

最优值是:0.00003
最优解是:x=0.00034,y=0.00014
粒子群优化算法——用PSO算法求解函数,最优解(0,0,...,0),Min=0_第3张图片

其他应用

粒子群优化算法在其他方面的应用:

  1. 机器学习与训练
  2. 数据挖掘与分类
  3. 生物与医学的应用
  4. 其他方面应用

你可能感兴趣的:(算法,算法,python)