【python】利用python实现简单粒子群优化算法实例

前言

最近在准备复(bai)习(lan)智能信息处理ing……想着通过复现一些PPT上简单算法例子的方式加深自己对算法的理解,也作为大家使用粒子群这一算法的思路与代码参考hhh

算法简述

粒子群算法(PSO)是1995年由美国社会心理学家J.Kennedy和电气工程师R.Eberhart共同提出,其基本思想是受到鸟类群体行为研究结果的启发,由于计算的快速性和易于实现从而引起重视。

PSO算法是通过随机化一群粒子的位置和运动速度,通过群体之间的联系和不同微粒之间个体的速率差异,通过一定的迭代规则,使其不断趋近于优化目标的真实解或解集,即求取最(极)大值或是最(极)小值的过程。

在这里,我们可以将每一个微粒个体看作是在n维搜索空间中的一个没有质量和体积的微粒,并在搜索空间中以一定的速度飞行,而飞行的速度由个体的飞行经验和群体的飞行经验进行动态调整。

在这里插入图片描述

我们以求函数最小值的优化问题帮助理解粒子群优化算法并尝试通过代码实现。

实例

今有如下Rosenbrock函数,求解其最小值:

f ( x , y ) = 100 ( y − x 2 ) 2 + ( 1 − x ) 2 f(x,y)=100(y-x^2)^2+(1-x)^2 f(x,y)=100(yx2)2+(1x)2

其中,限定定义域
x , y ∈ [ − 30 , 30 ] x,y\in[-30,30] x,y[30,30]

粒子最大速度 V m a x = 60 V_{max}=60 Vmax=60

函数大致图示如下:

在这里插入图片描述

由于问题的维数为2(x和y),所以我们每个粒子的速度和位置都应该是2维的向量,例如:

对于第i个粒子,有:

l o c a t i o n i = ( x i , y i ) location_i=(x_i,y_i) locationi=(xi,yi)
v = ( v x i , v y i ) v=(v_{xi},v_{yi}) v=(vxi,vyi)

紧接着对位置和速度进行随机数初始化,限定范围为[-30,30]即可。

接下来就是计算每个粒子的适应度(fitness)

适应度这一概念应用比较广泛,在遗传算法等一些其它优化算法中,这一名词也经常出现。在这里它表征的是每个粒子对于优化问题结果的评价指标,比如,以本例来说,我们希望找到函数的最小值以及取得最小值的点,那么我们就可以把本次实例的粒子适应度确定为粒子当前位置的函数值,函数值越小,意味着我们可能越接近最小值,即离我们的优化目标越近。

综上,我们可以通过直接求每个粒子的当前函数值来作为粒子当前的适应度。

在求取适应度值后,选取对于当前问题的局部最优解(个体历史最优解)全局最优解(群体历史最优解)

其中局部最优解指的是每一轮迭代后,所有粒子当前状态的适应度最大(小)值;全局最优解指的是所有粒子从开始迭代优化一直到现在的这一大段时间里出现过的适应度最大(小)值;当算法完成迭代轮次后,应该输出的是最终状态的全局最优解以及取得最优解的点。

接下来是更新粒子的速度和位置。

我们采用如下速度和位置的更新函数:

v k + 1 = w ∗ v k + c 1 ∗ ξ ( p k − x k ) + c 2 ∗ η ( p g − x k ) v_{k+1}=w*v_k+c_1*\xi(p_k-x_k)+c_2*\eta(p_g-x_k) vk+1=wvk+c1ξ(pkxk)+c2η(pgxk)
x k + 1 = x k + v k + 1 x_{k+1}=x_k+v_{k+1} xk+1=xk+vk+1

其中 w w w为惯性权重(调节对解空间搜索范围),本例取1, c 1 c_1 c1 c 2 c_2 c2系数为加速度常数,本例均取2, ξ \xi ξ η \eta η为(0,1)之间的随机数。

通过上述更新式完成对粒子位置和速度的更新(要注意一下,本例限定速度在任何一个维度不能超过60,但对于位置,一般不强行拉回解空间)。

重复上述步骤,直至达到迭代次数或迭代结果与真实值之间差值小于某一给定误差。

代码部分

这里直接给出全部过程代码,关键位置给出注释,欢迎大家有问题随时来讨论

# -*- coding:utf-8 -*-
# 2022/11/29
# Jonathan.K.Wolf
import numpy as np

"""
每一个粒子的形式:
z:
[x, y]
"""
# 种群规模
m = 5
# 迭代参数
c0 = 1
c1 = 2
c2 = 2


# 定义函数
def Rosenbrock(z):
    sum = 100.0 * np.power(z[1] - np.power(z[0], 2), 2) + np.power((1 - z[0]), 2)
    return sum


# 初始化种群
def init_group(size):
    group = []
    for i in range(size):
        group.append([])
    for i in range(size):
        for j in range(2):
            group[i].append(np.random.uniform(-30.0, 30.0))
    return group


# 初始化速度
def init_speed(size):
    speed = []
    for i in range(size):
        speed.append([])
    for i in range(size):
        for j in range(2):
            speed[i].append(np.random.uniform(-60.0, 60.0))
    return speed


# 计算适应度
def calculate_fitness(group):
    fitness = []
    for item in range(len(group)):
        fitness.append(Rosenbrock(group[item]))
    return fitness, fitness.index(min(fitness))


# 更新位置和速度
def update_loc_speed(group, speed, pk, pg):
    new_group = []
    new_speed = []
    for item in range(len(group)):
        new_group.append([])
        new_speed.append([])
    for item in range(len(group)):
        for index in range(len(group[0])):
            new_speed[item].append(
                speed[item][index] + 2 * np.random.rand() * (pk[index] - group[item][index]) + 2 * np.random.rand() * (
                        pg[index] - group[item][index]))
            new_group[item].append(group[item][index] + new_speed[item][index])
    # 限定速度范围
    for item in range(len(speed)):
        for index in range(len(speed[0])):
            if new_speed[item][index] > 60.0:
                new_speed[item][index] = 60.0
            if new_speed[item][index] < -60.0:
                new_speed[item][index] = -60.0
    return new_group, new_speed


# 主要过程迭代
def process():
    epoch = 100000
    group_real = init_group(5)
    speed_real = init_speed(5)
    # 历史最优解
    history_best = group_real[0]
    # 当前最优解
    p = []

    # print(group_real)
    # print(speed_real)
    for i in range(epoch):
        fitness_real, pg_ = calculate_fitness(group_real)
        p.append(group_real[pg_])
        if Rosenbrock(p[i]) <= Rosenbrock(history_best):
            history_best = p[i]
        group_real, speed_real = update_loc_speed(group_real, speed_real, p[i], history_best)
        if i % 100 == 0:
            # print("current epoch:%d, current solution:%e" % (i, Rosenbrock(history_best)))
            print("current epoch:{}, current solution:{}".format(i, history_best))
    print(
        "the answer after {} epoch is ({},{}), and current value is {}".format(epoch, history_best[0], history_best[1],
                                                                               Rosenbrock(history_best)))


if __name__ == '__main__':
    process()

运行结果

在这里插入图片描述
100000轮次下得到最小值点及结果如图,与真实点(1,1)和最小值0相差无几,成功印证了算法的可用性

当然本篇只是实现最基本的粒子群优化算法,针对于优化问题的更优算法和改进方式还有很多,篇幅有限,这里不再详细解读了hhh

最后也欢迎各位大佬有问题随时批评指正~

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
柔性车间调度问题是指在车间生产过程中,根据不同的工件加工顺序、加工时间、设备可用性等因素进行合理的调度,以最大程度地提高生产效率和资源利用率。粒子群优化算法是一种求解优化问题的启发式算法,它模拟鸟群觅食的行为,通过不断调整个体的位置和速度来寻找最优解。在这里,我们将使用Python实现基于改进粒子群优化算法的柔性车间调度问题。 首先,我们需要定义柔性车间调度问题的目标函数,包括最小化总加工时间、最小化设备的空闲时间等。然后,我们可以使用Python编写粒子群优化算法的主要逻辑,包括初始化粒子群、更新粒子位置和速度、评估每个粒子的适应度并更新全局最优解等步骤。 在实现过程中,我们可以根据问题特点对标准粒子群优化算法进行改进,比如引入惯性权重、自适应调整惯性权重、多种邻域结构的搜索、局部搜索策略等,以增强算法的全局搜索能力和收敛速度。 最后,我们可以使用实际的柔性车间调度实例来验证我们实现的改进粒子群优化算法的有效性和性能。通过打印调度结果和统计各项指标来评估算法的优化效果,并对算法进行参数调整和优化。 总之,基于改进粒子群优化算法的柔性车间调度问题的Python实现是一个复杂而有挑战的工作,需要对算法原理有深入的理解,并结合实际问题进行合理的改进和优化。希望我们的实现能够为柔性车间调度问题的解决提供一些新的思路和方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值