首页 > 编程语言 >粒子群算法(主要针对连续型函数优化问题)

粒子群算法(主要针对连续型函数优化问题)

时间:2024-04-02 21:34:03浏览次数:32  
标签:粒子 max 连续型 算法 ij quad 最优 best

文章主要参考了以下博文:

https://zhuanlan.zhihu.com/p/564819718

1. 简介

粒子群算法是一种解决最优化问题的通用方法,其优点是求解速度快,数值相对稳定,算法简单。粒子群算法分为连续型粒子群算法和离散型粒子群算法,分别用于解决连续型问题和离散型问题。

粒子群优化算法源自对鸟群捕食行为的研究:一群鸟在区域中随机搜索食物,搜索的策略就是搜寻目前离食物最近的鸟的周围区域。粒子群算法利用这种模型得到启示并应用于解决优化问题:

  • 鸟类的飞行空间: 搜索空间,也可以理解为约束

  • 鸟(粒子): 可行解

  • 鸟类寻找到的食物源: 最优解

在粒子群算法中,每个优化问题的潜在解都是搜索空间中的一只鸟,称之为粒子(在连续性例子群算法中,每一个粒子就代表一个可行解)。所有的粒子都有一个由被优化的函数决定的适应度值,每个粒子还有一个速度决定它们飞翔的方向和距离。然后,粒子们就追随当前的最优粒子在解空间中搜索。

粒子群算法首先在给定的解空间中随机初始化粒子群,待优化问题的变量数决定了解空间的维数(这里表示每个粒子的维度,后面我们会用D表示维度)。每个粒子有了初始位置与初始速度(x表示当前位置,v表示速度,粒子群算法最重要的是对速度公式的更新,因为速度决定了更新的方向,进而决定解的值),然后通过迭代寻优。在每一次迭代中,每个粒子通过跟踪两个“极值”来更新自己在解空间中的空间位置与飞行速度:一个极值就是单个粒子本身在迭代过程中找到的最优解粒子,这个粒子叫作个体极值;(这里的意思是,每个粒子具有记忆性,每个粒子子记得两个值,一个是全部的粒子距离目标的最优值,另一个值是这个粒子曾经历史的最优值) 另一个极值是种群所有粒子在迭代过程中所找到的最优解粒子,这个粒子是全局极值。

2. 连续型粒子群优化算法

2.1 基本原理

假设在一个\(D维\)的目标搜索空间中,有\(N\)个粒子组成一个群落,其中第\(i\)个粒子表示一个\(D维\)的向量:

\[X_i=(x_{i1},x_{i2},\dots,x_{iD}),\quad{i}=1,2,\dots,N\quad\quad(1) \]

第\(i\)个粒子的“飞行”速度也是一个\(D维\)向量:

\[V_i=(v_{i1},v_{i2},\dots,v_{iD}),\quad{i}=1,2,\dots,N\quad\quad\quad(2) \]

第\(i\)个粒子迄今为止搜到的最优位置称为个体极值(比如:\((p_{11},p_{12},\dots,p_{1D})\)就是第一个粒子搜索到的最优位置),记为:

\[p_{best}=(p_{i1},p_{i2},\dots,p_{iD}),\quad{i}=1,2,\dots,N\quad\quad(3) \]

整个粒子群迄今为止搜索到的最优位置为全局极值(我的理解是\(g_{best}\)就是本次迭代的局部最优解),记为:

\[g_{best}=(g_{1},g_{2},\dots,g_{D})\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad(4) \]

在找到这两个最优值时,粒子根据如下的式(5)和式(6)分别来更新自己的速度和位置:

\[v_{ij}(t+1)=v_{ij}(t)+c_1r_1[p_{ij}(t)-x_{ij}(t)]+c_2r_2[p_{gj}(t)-x_{ij}(t)]\quad(5) \]

\[x_{ij}(t+1)=x_{ij}(t)+v_{ij}(t+1)\quad\quad\quad\quad\quad\quad\quad\quad(6) \]

式(5)和式(6)是整个粒子群算法最核心的部分,对于式(5),其中:

  • \(c_1\)和\(c_2\)为学习因子,也称加速常数;

  • \(r_1\)和\(r_2\)为\([0,1]\)范围内的均匀随机数;\(r_1\)和\(r_2\)是介于0和1之间的随机数,增加了粒子飞行的随机性

  • \(j=1,2,…,D\);

  • \(v_{ij}\)是粒子的速度,\(v_{ij}∈[-v_{max},v_{max}]\),\(v_{max}\)是常数,由用户设定来限制粒子的速度。

  • 式(5)右边由三部分组成:

    • 第一部分为“惯性”或“动量”部分,反映了粒子的运动“习惯”,代表粒子有维持自己先前速度的趋势(就是原有的速度);

    • 第二部分为“认知”部分,反映了粒子对自身历史经验的记忆或回忆,代表粒子有向自身历史最佳位置逼近的趋势;

    • 第三部分为“社会”部分,反映了粒子间协同合作与知识共享的群体历史经验,代表粒子有向群体或邻域历史最佳位置逼近的趋势(对于\(p_{gj}\),我的理解是把\(p_{best}\)的最优值中的\(i\)下标的值记为\(g\),或者换句话来说,\(p_{gj}(t)\)就是整个群体的历史最佳位置)。

上面的是基本粒子群算法,下面的标准粒子群算法的更新是这样的,就是在速度\(v_{ij}\)的前面加一个权重系数\(w\)。使得权重系数是一个动态调整的。保证在迭代前期保证足够的全局搜索能力,迭代后期能够专注于局部最优解的搜索能力。

\[v_{ij}(t+1)=w·v_{ij}(t)+c_1r_1[p_{ij}(t)-x_{ij}(t)]+c_2r_2[p_{gj}(t)-x_{ij}(t)]\quad(7) \]

\[x_{ij}(t+1)=x_{ij}(t)+v_{ij}(t+1)\quad\quad\quad\quad\quad\quad\quad\quad(8) \]

权重更新公式如下(这是其中一种,还有其他的更新方式):

\[w=w_{max}-\frac{(w_{max}-w_{min})·t}{T_{max}}\quad\quad\quad\quad\quad\quad\quad\quad(9) \]

2.2 算法流程

(1)初始化粒子群,包括群体规模\(N\),每个粒子的位置\(x_i\)和速度\(v_i\)。

(2)计算每个粒子的适应度值\(fitness_i\)。

(3)对每个粒子,用它的适应度值\(fitness_i\)和个体极值\(p_{best}(i)\)比较。如果\(fitness_i<p_{best}(i)\),则用\(fitness_i\)替换掉\(p_{best}(i)\)。

(4)对每个粒子,用它的适应度值\(fitness_i\)和全局极值\(g_{best}\)比较。如果\(fitness_i<g_{best}\),则用\(fitness_i\)替换\(g_{best}\)。

(5)迭代更新粒子的速度\(v_i\)和位置\(x_i\)。

(6)进行边界条件处理。

(7)判断算法终止条件是否满足:若是,则结束算法并输出优化结果;否则返回步骤(2)。

2.3 算法详解

求函数\(f(x,y)=3cos(xy)+x+y^2\)的最小值,其中\(x\)的取值范围为\([-4,4]\),y的取值范围为\([-4,4]\)。为了方便编程,在算法中,\(x\)用\(x[0]\)表示,\(y\)用\(x[1]\)来表示。

2.3.1 绘图

首先我们来看看\(f(x,y)=3cos(xy)+x+y^2\)函数长啥样:

# 求函数f(x,y) = 3*cos(x * y) + x + y**2的最小值,其中-4 <= x <= 4, -4 <= y <= 4

# 首先绘制这个函数的三维图像
import numpy as np
import matplotlib.pyplot as plt

X = np.arange(-4 ,4 ,0.01)
Y = np.arange(-4 ,4 ,0.01)
x, y = np.meshgrid(X ,Y)
Z = 3*np.cos(x * y) + x + y**2

# 作图
fig = plt.figure(figsize=(10,15))
ax3 = plt.axes(projection = "3d")
ax3.plot_surface(x,y,Z ,cmap = "rainbow")
# ax3.contour(x ,y ,Z ,zdim = "z" ,offset=-2 ,cmap = "rainbow")
plt.show()

2.3.2 连续型粒子群算法求解

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
# 设置字体和设置负号
matplotlib.rc("font", family="KaiTi")
matplotlib.rcParams["axes.unicode_minus"] = False
# 初始化种群,群体规模,每个粒子的速度和规模
N = 100 # 种群数目
D = 2 # 维度
T = 200 # 最大迭代次数
c1 = c2 = 1.5 # 个体学习因子与群体学习因子
w_max = 0.8 # 权重系数最大值
w_min = 0.4 # 权重系数最小值
x_max = 4 # 每个维度最大取值范围,如果每个维度不一样,那么可以写一个数组,下面代码依次需要改变
x_min = -4 # 同上
v_max = 1 # 每个维度粒子的最大速度
v_min = -1 # 每个维度粒子的最小速度


# 定义适应度函数
def func(x):
    return 3 * np.cos(x[0] * x[1]) + x[0] + x[1] ** 2


# 初始化种群个体
x = np.random.rand(N, D) * (x_max - x_min) + x_min # 初始化每个粒子的位置
v = np.random.rand(N, D) * (v_max - v_min) + v_min # 初始化每个粒子的速度

# 初始化个体最优位置和最优值
p = x # 用来存储每一个粒子的历史最优位置
p_best = np.ones((N, 1))  # 每行存储的是最优值
for i in range(N): # 初始化每个粒子的最优值,此时就是把位置带进去,把适应度值计算出来
    p_best[i] = func(x[i, :])

# 初始化全局最优位置和全局最优值
g_best = 100 #设置真的全局最优值
gb = np.ones(T) # 用于记录每一次迭代的全局最优值
x_best = np.ones(D) # 用于存储最优粒子的取值

# 按照公式依次迭代直到满足精度或者迭代次数
for i in range(T):
    for j in range(N):
        # 个更新个体最优值和全局最优值
        if p_best[j] > func(x[j,:]):
            p_best[j] = func(x[j,:])
            p[j,:] = x[j,:].copy()
        # p_best[j] = func(x[j,:]) if func(x[j,:]) < p_best[j] else p_best[j]
        # 更新全局最优值
        if g_best > p_best[j]:
            g_best = p_best[j]
            x_best = x[j,:].copy()   # 一定要加copy,否则后面x[j,:]更新也会将x_best更新
        # 计算动态惯性权重
        w = w_max - (w_max - w_min) * i / T
        # 更新位置和速度
        v[j, :] = w * v[j, :] + c1 * np.random.rand(1) * (p[j, :] - x[j, :]) + c2 * np.random.rand(1) * (x_best - x[j, :])
        x[j, :] = x[j, :] + v[j, :]
        # 边界条件处理
        for ii in range(D):
            if (v[j, ii] > v_max) or (v[j, ii] < v_min):
                v[j, ii] = v_min + np.random.rand(1) * (v_max - v_min)
            if (x[j, ii] > x_max) or (x[j, ii] < x_min):
                x[j, ii] = x_min + np.random.rand(1) * (x_max - x_min)
    # 记录历代全局最优值
    gb[i] = g_best
print("最优值为", gb[T - 1],"最优位置为",x_best)
plt.plot(range(T),gb)
plt.xlabel("迭代次数")
plt.ylabel("适应度值")
plt.title("适应度进化曲线")
plt.show()

标签:粒子,max,连续型,算法,ij,quad,最优,best
From: https://www.cnblogs.com/zoubilin/p/18111561

相关文章

  • 代码随想录算法训练营第14天 | 二叉树 | 二叉树的遍历 | 迭代遍历 |统一风格的迭代(待
    理论基础二叉树的存储方式:可以链式也可以顺序用数组顺序存储二叉树的遍历递归遍历递归算法三要素确定递归函数的参数和返回值确定终止条件确定单层递归的逻辑风格不统一的迭代遍历(前后和中序的不同)前序遍历(根左右)//递归版voidtraversal(TreeNode*......
  • 高精度算法(加、减、乘、除,使用c++实现)
    一、概念在我们进行计算的过程中,经常会遇到几十位,甚至几百位的数字的计算问题,也有可能会遇到小数点后几十位,几百位的情况,而我们面对这样的情况下,  和  的数据范围显然是不够使用的了。因此这时,我们就需要引入一个新的算法,叫做高精度算法。高精度算法:它是处理大数字的数......
  • KMP&&哈希算法
    KMP算法KMP算法是一种字符串匹配算法,用于匹配模式串P在文本串S中出现的所有位置。例如S=“ababac”,P="aba",那么出现的所有位置是13KMP算法将原本O(n^2)的字符串匹配算法优化到了O(n),其精髓在于next数组,next数组表示此时模式串下标失配时应该移动到的位置,(每次下标失配时,就是i!......
  • 代码随想录算法训练营DAY14|C++二叉树Part.1|二叉树的递归遍历、二叉树的迭代遍历、二
    文章目录二叉树的递归遍历思路CPP代码二叉树的迭代遍历思路前序遍历后序遍历后序遍历二叉树的统一迭代法二叉树的递归遍历144.二叉树的前序遍历、145.二叉树的后序遍历、94.二叉树的中序遍历文章讲解:二叉树的递归遍历视频讲解:每次写递归都要靠直觉?这次带你学......
  • 【C++算法】 卡常技巧
    文章目录updata学习引言技巧1——善用修饰符技巧2——输入输出`read`和`write`技巧3——对于运算的优化技巧4——展开循环技巧5——对与循环的优化updata2024.03.31发布此文章学习引言卡常,一种编程技巧,在对时间复杂度要求很高时,就可以用这种办法来节省时......
  • 常见面试算法题-报文解压缩
    ■ 题目描述为了提升数据传输的效率,会对传输的报文进行压缩处理。输入一个压缩后的报文,请返回它解压后的原始报文。压缩规则:n[str],表示方括号内部的str正好重复n次。注意n为正整数(0<n<=100),str只包含小写英文字母,不考虑异常情况。输入描述:输入压缩后的报文:1)不考......
  • 自然语言处理基础知识入门(二) Word2vec模型,层次softmax,负采样算法详解
    文章目录前言一、Word2vec模型1.1什么是Word2vec模型?1.2Word2vec模型是如何训练?1.3Word2vec最简单版本整体过程1.4Word2vec详细过程1.5CBOW整体过程1.6Skip-gram整体过程二、优化算法2.1层次softmax2.1.1哈夫曼树2.1.2算法详细逻辑2.2负采样策略总结......
  • 优化之前的ocr算法
    importtorch.nnasnnfromcollectionsimportOrderedDictclassBidirectionalLSTM(nn.Module):def__init__(self,nIn,nHidden,nOut):super(BidirectionalLSTM,self).__init__()self.rnn=nn.LSTM(nIn,nHidden,bidirectional=True)......
  • 14天【代码随想录算法训练营34期】 第六章 二叉树part01(● 理论基础 ● 递归遍历 ●
    理论基础种类满二叉树:k是深度,node数为2^k-1完全二叉树:二叉树底部是从左向右持续的二叉搜索树:左边节点都小于中间节点,右边节点都大于中间节点平衡二叉树AVL:左边和右边高度相差不超过1存储方式链式存储:leftchildptr,rightchildptr线式存储:字符数组保存,2i+1是左孩......
  • 使用支持向量机算法解决手写体识别问题
    文章目录支持向量机导入图片测试算法fromgoogle.colabimportdrivedrive.mount("/content/drive")Drivealreadymountedat/content/drive;toattempttoforciblyremount,calldrive.mount("/content/drive",force_remount=True).支持向量机fromnumpy......