最值问题—粒子群算法(PSO)python实现

粒子群算法:

  • PSO比较有潜力的应用领域有多目标优化,分类,模式识别,决策等
  • PSO存在的问题:应当与其它算法结合,解决PSO易陷于局部最优的问题

粒子群“实体”:
在这里插入图片描述
粒子群算法流程:
在这里插入图片描述
粒子群更新:
速度更新公式:
在这里插入图片描述位置更新公式:
在这里插入图片描述
线性递减权值:
wd=wstart-(wstart - wend)x (d/K)
d是当前迭代的次数,K是迭代总次数,wstart一般取0.9,wend一般取0.4
较大的w有较好的全局收敛能力,较小的w则有较强的局部收敛能力,因此,随着迭代次数的增加,惯性权重w应不断减少,从而使得粒子群算法在初期具有较强的全局收敛能力,而晚期具有较强的局部收敛能力

全部代码:

# -*- coding: utf-8 -*-
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, dim, time, size, low, up, v_low, v_high):
        # 初始化
        self.dim = dim          # 变量个数
        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.dim))  # 所有粒子的位置
        self.v = np.zeros((self.size, self.dim))  # 所有粒子的速度
        self.p_best = np.zeros((self.size, self.dim))  # 每个粒子最优的位置
        self.g_best = np.zeros((1, self.dim))[0]  # 全局最优的位置
        # 初始化第0代初始全局最优解
        temp = -1000000
        for i in range(self.size):
            for j in range(self.dim):
                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):
        """
            个体适应值计算
        """
        y = 0
        for i in range(dim-1):
            y += 100*(x[i+1]-x[i]**2)**2 + (x[i]-1)**2
        return y

    def update(self, size):
        """"
            保证了全局一定小于局部
        """
        c1 = 2.0  # 学习因子
        c2 = 2.0
        wstart = 0.9
        wend = 0.4
        for i in range(size):
            # 更新速度(核心公式)
            w = wstart - (wstart - wend) * (i+1) / self.time    # 更新惯性权重
            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.dim):
                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.dim):
                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])
        # 迭代次数
        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
    dim = 4
    v_low = -1
    v_high = 1
    low = [-30, -30, -30, -30]
    up = [30, 30, 30, 30]
    pso = PSO(dim, time, size, low, up, v_low, v_high)
    pso.pso()

运行结果:
在这里插入图片描述

参考:https://blog.csdn.net/weixin_44580451/article/details/109503819?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161628781016780271552699%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161628781016780271552699&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-4-109503819.first_rank_v2_pc_rank_v29&utm_term=%E7%BA%BF%E6%80%A7%E9%80%92%E5%87%8FPSO
https://blog.csdn.net/Cyril_KI/article/details/108589078?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161624704016780269858599%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161624704016780269858599&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~hot_rank-4-108589078.first_rank_v2_pc_rank_v29&utm_term=PSO+python

猜你喜欢

转载自blog.csdn.net/weixin_45666249/article/details/115040547