粒子群算法(PSO)的Python实现(求解多元函数的极值)

PSO算法算是寻优算法中比较简单的一种,其大概思想是:
在这里插入图片描述
现在我们计算:
在这里插入图片描述
的极大值,每一个变量的取值范围都是(1,25)。
Python代码为:

# -*- coding: utf-8 -*-
"""
@Time : 2020/9/13 10:08
@Author :KI 
@File :pso.py
@Motto:Hungry And Humble

"""
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, dimension, time, size, low, up, v_low, v_high):
        # 初始化
        self.dimension = dimension  # 变量个数
        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.dimension))  # 所有粒子的位置
        self.v = np.zeros((self.size, self.dimension))  # 所有粒子的速度
        self.p_best = np.zeros((self.size, self.dimension))  # 每个粒子最优的位置
        self.g_best = np.zeros((1, self.dimension))[0]  # 全局最优的位置

        # 初始化第0代初始全局最优解
        temp = -1000000
        for i in range(self.size):
            for j in range(self.dimension):
                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):
        """
        个体适应值计算
        """
        x1 = x[0]
        x2 = x[1]
        x3 = x[2]
        x4 = x[3]
        x5 = x[4]
        y = math.floor((x2 * np.exp(x1) + x3 * np.sin(x2) + x4 + x5) * 100) / 100
        # print(y)
        return y

    def update(self, size):
        c1 = 2.0  # 学习因子
        c2 = 2.0
        w = 0.8  # 自身权重因子
        for i in range(size):
            # 更新速度(核心公式)
            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.dimension):
                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.dimension):
                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, 5])
        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
    dimension = 5
    v_low = -1
    v_high = 1
    low = [1, 1, 1, 1, 1]
    up = [25, 25, 25, 25, 25]
    pso = PSO(dimension, time, size, low, up, v_low, v_high)
    pso.pso()

运行结果:
在这里插入图片描述
收敛过程:
在这里插入图片描述
可以看出,不到10次就收敛了。

matlab代码:

z=@(x)-(x(2)*exp(x(1))+x(3)*sin(x(2))+x(4)*x(5));
x0=[1;1;1;1;1];
[x,feval]=fmincon(z,x0,[],[],[],[],[1;1;1;1;1],[25;25;25;25;25])

运行结果:

x =

   25.0000
   25.0000
   13.1400
    1.0002
    1.0002


feval =
  -1.8001e+12

如果想要利用上述代码求极小值,可以有以下两种办法:

  1. 将fitness函数中的返回值改为-y,此时如果求出的值为z,那么函数的极小值就为-z。
  2. 将第34行代码处的temp改为一个很大的值;将第42、83、85以及93行代码处的">“改为”<"。
  • 58
    点赞
  • 484
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 26
    评论
粒子群算法是一种优化算法,可以用于求解一元函数的最小值或最大值。下面是使用Python实现粒子群算法求解一元函数最小值的示例代码: ```python import random # 定义目标函数 def func(x): return x**2 # 粒子群算法 class PSO(): def __init__(self, dim, size, iter_num, c1, c2, w): self.dim = dim # 粒子维度 self.size = size # 粒子群大小 self.iter_num = iter_num # 迭代次数 self.c1 = c1 # 学习因子1 self.c2 = c2 # 学习因子2 self.w = w # 惯性权重 self.x_bound = [-10, 10] # 粒子的取值范围 self.x = [[random.uniform(self.x_bound[0], self.x_bound[1]) for _ in range(self.dim)] for _ in range(self.size)] # 初始化粒子的位置 self.v = [[random.random() for _ in range(self.dim)] for _ in range(self.size)] # 初始化粒子的速度 self.pbest = self.x # 个体最优位置 self.gbest = self.x[0] # 全局最优位置 # 更新速度和位置 def evolve(self): for i in range(self.size): # 更新速度 for j in range(self.dim): r1 = random.random() r2 = random.random() self.v[i][j] = self.w*self.v[i][j] + self.c1*r1*(self.pbest[i][j]-self.x[i][j]) + self.c2*r2*(self.gbest[j]-self.x[i][j]) # 更新位置 for j in range(self.dim): self.x[i][j] += self.v[i][j] # 越界处理 if self.x[i][j] < self.x_bound[0]: self.x[i][j] = self.x_bound[0] elif self.x[i][j] > self.x_bound[1]: self.x[i][j] = self.x_bound[1] # 更新个体最优位置 if func(self.x[i]) < func(self.pbest[i]): self.pbest[i] = self.x[i] # 更新全局最优位置 if func(self.x[i]) < func(self.gbest): self.gbest = self.x[i] # 运行粒子群算法 def run(self): for i in range(self.iter_num): self.evolve() print('iteration:', i, 'gbest:', func(self.gbest)) return self.gbest # 测试 pso = PSO(dim=1, size=20, iter_num=100, c1=2, c2=2, w=0.8) print(pso.run()) ``` 上述代码中,我们定义了一个目标函数`func(x)`,并使用粒子群算法求解函数的最小值。在`PSO`类中,我们定义了粒子群算法的各个参数,包括粒子维度`dim`、粒子群大小`size`、迭代次数`iter_num`、学习因子`c1`和`c2`、惯性权重`w`等。在初始化时,我们随机生成粒子的位置和速度,并将其限制在一个取值范围内。在每次迭代中,我们根据当前的速度和位置更新粒子的位置,并更新个体最优位置和全局最优位置。最后,我们运行粒子群算法,并输出最终的全局最优位置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cyril_KI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值