Optimal value problem-particle swarm optimization (PSO) python implementation

Particle swarm algorithm:

  • PSO has more potential application areas such as multi-objective optimization, classification, pattern recognition, decision-making, etc.
  • Problems with PSO: It should be combined with other algorithms to solve the problem of PSO easily falling into local optimality

Particle swarm "entity":
Insert picture description here
particle swarm algorithm process:
Insert picture description here
particle swarm update:
speed update formula:
Insert picture description hereposition update formula:
Insert picture description here
linearly decreasing weight:
wd=wstart-(wstart-wend)x (d/K)
d is the number of current iterations, K is the total number of iterations, wstart generally takes 0.9, wend generally takes 0.4.
Larger w has better global convergence ability, and smaller w has stronger local convergence ability. Therefore, as the number of iterations increases, inertia The weight w should be continuously reduced, so that the particle swarm algorithm has strong global convergence ability in the early stage, and strong local convergence ability in the late stage.

All codes:

# -*- 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()

operation result:
Insert picture description here

Reference: 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-2 all sobaiduend~default-4-109503819.first_rank_v2_pc_rank_v29&utm_term=%E7%BA%BF%E6%80%A7%E9%80% %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.130Fall102334.pc% .%2522%257D&request_id=161624704016780269858599&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2 allfirst_rank_v2~hot_rank-4-108589078.first_rank_v2_pc_rank_v29&utm_term=PSO+python

Guess you like

Origin blog.csdn.net/weixin_45666249/article/details/115040547