粒子群优化算法(Particle Swarm Optimization,PSO)的python代码实现。

本文详细介绍了如何在Python中实现粒子群优化算法PSO,包括适应度函数定义、PSO类的初始化、速度和位置的更新过程,以及如何处理全局最优值的保存。作者还指出了原始代码中的一个小问题,并提供了修正后的代码段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文代码是对这篇文章代码的一个优化:

粒子群优化算法(PSO)python实践_python粒子群优化算法_MSTIFIY的博客-优快云博客

直接上代码:

import numpy as np
import random
import matplotlib.pyplot as plt
import time 
import copy

def Fitness(x):  # 适应度函数
    fitness_value = x[0] * np.exp(x[1]) + x[2] * np.sin(x[1]) + x[3] * x[4] * x[5]
    return fitness_value

class PSO(object):
    def __init__(self, Dim, Num_Particle, Max_iter, p_low, p_up, v_low, v_high, w = 1., c1 = 2., c2 = 2.):
        self.w = w  # 惯性权值
        self.c1 = c1  # 个体学习因子
        self.c2 = c2  # 群体学习因子
        self.D = Dim  # 粒子维度  
        self.N = Num_Particle  # 粒子群规模,初始化种群个数  100
        self.Max_iter = Max_iter  # 最大迭代次数  50
        self.p_range = [p_low, p_up]  # 粒子位置的约束范围
        self.v_range = [v_low, v_high]  # 粒子速度的约束范围
        self.x = np.zeros((self.N, self.D))  # 粒子群的位置
        self.v = np.zeros((self.N, self.D))  # 粒子群的速度
        self.p_best = np.zeros((self.N, self.D))  # 每个粒子的最优位置
        self.g_best = np.zeros((1, self.D))[0]  # 种群(全局)的最优位置
        self.p_bestFit = np.zeros(self.N)  # 每个粒子的最优适应值
        self.g_bestFit = float('Inf')  # 初始的全局最优适应度

        # 初始化所有个体和全局信息
        for i in range(self.N):
            for j in range(self.D):
                self.x[i][j] = random.uniform(self.p_range[0][j], self.p_range[1][j])
                self.v[i][j] = random.uniform(self.v_range[0], self.v_range[1])
            self.p_best[i] = self.x[i]  # 保存个体历史最优位置,初始默认第0代为最优
            fit = Fitness(self.p_best[i])
            self.p_bestFit[i] = fit  # 保存个体历史最优适应值
            if fit < self.g_bestFit:  # 寻找并保存全局最优位置和适应值
                self.g_best = self.p_best[i]
                self.g_bestFit = fit

    def interate(self, draw = 1):  
        best_fit = []  # 记录每轮迭代的最佳适应度,用于绘图
        w_range = None
        if isinstance(self.w, tuple):
            w_range = self.w[1] - self.w[0]
            self.w = self.w[1]
        time_start = time.time()  # 记录迭代寻优开始时间
        for i in range(self.Max_iter):
            self.update()  # 更新主要参数和信息
            if w_range:
                self.w -= w_range / self.Max_iter  # 惯性权重线性递减
            print("\rIter: {:d}/{:d} fitness: {:.4f} ".format(i, self.Max_iter, self.g_bestFit, end = '\n'))
            best_fit.append(self.g_bestFit.copy())
        time_end = time.time()  # 记录迭代寻优结束时间
        print(f'Algorithm takes {time_end - time_start} seconds')  # 打印算法总运行时间,单位为秒/s
        if draw:
            plt.figure()
            plt.plot([i for i in range(self.Max_iter)], best_fit)
            plt.xlabel("iter")
            plt.ylabel("fitness")
            plt.title("Iter process")
            plt.show()
    
    def update(self):
        for i in range(self.N):

            # 更新速度
            self.v[i] = self.w * self.v[i] + self.c1 * random.uniform(0, 1) * (
                    self.p_best[i] - self.x[i]) + self.c2 * random.uniform(0, 1) * (self.g_best - self.x[i])
            
            # 速度限制
            for j in range(self.D):
                if self.v[i][j] < self.v_range[0]:
                    self.v[i][j] = self.v_range[0]
                if self.v[i][j] > self.v_range[1]:
                    self.v[i][j] = self.v_range[1]

            # 更新位置
            self.x[i] = self.x[i] + self.v[i]

            # 位置限制
            for j in range(self.D):
                if self.x[i][j] < self.p_range[0][j]:
                    self.x[i][j] = self.p_range[0][j]
                if self.x[i][j] > self.p_range[1][j]:
                    self.x[i][j] = self.p_range[1][j]

            # 更新个体和全局历史最优位置及适应值
            _fit = Fitness(self.x[i])
            if _fit < self.p_bestFit[i]:
                self.p_best[i] = copy.copy(self.x[i])
                self.p_bestFit[i] = _fit
            if _fit < self.g_bestFit:
                self.g_best = copy.copy(self.x[i])
                self.g_bestFit = _fit

if __name__ == '__main__':

    low = [1, 1, 1, 1, 1, 1]
    up = [25, 25, 25, 25, 25, 25] # Dim 等于要寻优参数的维度

    pso = PSO(Dim=6, Num_Particle=100, Max_iter=50, p_low=low, p_up=up, 
              v_low=-1, v_high=1, w = 0.9, c1 = 2., c2 = 2.)  # 初始化
    
    pso.interate(draw = 1)  # 迭代开始, draw = 1表示绘图

主要修改的地方在于:

'''
修改前
'''
_fit = self.fitness(self.x[i])
if _fit < self.p_bestFit[i]:
    self.p_best[i] = self.x[i]
    self.p_bestFit[i] = _fit
if _fit < self.g_bestFit:
    self.g_best = self.x[i]
    self.g_bestFit = _fit

'''
修改后
'''
_fit = Fitness(self.x[i])
if _fit < self.p_bestFit[i]:
    self.p_best[i] = copy.copy(self.x[i])
    self.p_bestFit[i] = _fit
if _fit < self.g_bestFit:
    self.g_best = copy.copy(self.x[i])
    self.g_bestFit = _fit

self.g_best = self.x[i]这样的赋值语句中,获取的是 self.x[i]的引用。在原始代码中,只要判断语句 if _fit < self.g_bestFit 成立一次, self.g_best 的值就一直等于变量 self.x[i]的值,即self.g_best保存的不是全局最优解。

在Python中,可以使用copy模块来进行对象的复制。具体来说,因为self.x[i]是可变对象(如列表),可以使用copy.copy进行浅复制,如果是不可变对象(如数字、字符串等),可以使用copy.deepcopy进行深复制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值