Python实现粒子群算法

一、推荐粒子群理论教程

优化算法笔记(三)粒子群算法(1) - 简书

二、Python实现代码

# -*- coding: utf-8 -*-

import numpy as np

np.random.seed(20)

'''
    设x0:价格,x1:促销,x2:竞品价格 x为三维数据
    实际情况这里应该是,比如:  利润 = F销量(x0,x1,x2) * x0 - 成本,其中F销量为调用销量预测的结果
    两种方案:一是fitfun作为参数传入,二是该条销量预测样本数据作为参数传入
'''


def get_max_lirun(x):
    # 更新features中的x
    # 调用销量预测模型获得结果
    # 计算适应度值
    f_value = (-2 * x[0, 0]) + (4000 * x[0, 1]) + (4000 * x[0, 2])
    return f_value


class Particle(object):
    '''
    粒子类
    __x: 粒子位置
    __v: 粒子速度
    __bestX: 粒子历史最优位置
    __fitnessValue: 粒子历史最优适应度
    '''

    def __init__(self, min_x, max_x, max_v, dim, fitness_fun):
        self.__x = np.array([np.random.uniform(i, j) for i, j in zip(min_x, max_x)]).reshape(1, -1)
        self.__v = np.array([np.random.uniform(-i, i) for i in max_v]).reshape(1, -1)
        self.__bestX = np.zeros((1, dim))
        self.__fitnessValue = fitness_fun(self.__x)

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, x):
        if x.shape == self.__x.shape:
            self.__x = x
        else:
            print('输入维度错误!')

    @property
    def v(self):
        return self.__v

    @v.setter
    def v(self, v):
        if v.shape == self.__v.shape:
            self.__v = v
        else:
            print('输入维度错误!')

    @property
    def bestX(self):
        return self.__bestX

    @bestX.setter
    def bestX(self, bestX):
        self.__bestX = bestX

    @property
    def fitnessValue(self):
        return self.__fitnessValue

    @fitnessValue.setter
    def fitnessValue(self, f_value):
        self.__fitnessValue = f_value


class PSO(object):
    '''
    粒子群算法
    W: 惯性系数
    C1: 自我学习因子
    C2: 全局学习因子
    dim: 维度数(位置维度、速度维度一致)
    p_num: 粒子个数
    max_x: 位置范围(这里设为[-max_x,max_x]),实际场景需要再设置min_x
    max_v: 速度范围,实际场景需要再设置min_v
    iter_num: 迭代次数
    bestf_val: 群体历史最优适应度
    best_val_list: 历史迭代最优适应度记录
    particles: 粒子群
    '''

    def __init__(self, W, C1, C2, dim, p_num, min_x, max_x, max_v, iter_num, fitness_fun, bestf_val=-np.inf):
        self.__W = W
        self.__C1 = C1
        self.__C2 = C2
        self.__dim = dim
        self.__min_x = np.array(min_x).reshape(1, -1)
        self.__max_x = np.array(max_x).reshape(1, -1)
        self.__max_v = np.array(max_v).reshape(1, -1)
        self.__iter_num = iter_num
        self.__G = np.zeros((1, dim))
        self.__bestf_val = bestf_val
        self.__bestf_val_list = []
        self.__fitness_fun = fitness_fun
        self.__particles = [Particle(min_x, max_x, max_v, dim, fitness_fun) for i in range(p_num)]

    @property
    def G(self):
        return self.__G

    @property
    def bestf_val_list(self):
        return self.__bestf_val_list

    @property
    def bestf_val(self):
        return self.__bestf_val

    def update_all(self):
        for i in range(self.__iter_num):
            print('迭代第{}次'.format(i))
            for p in self.__particles:
                self._update_v(p)  # 更新粒子速度
                self._update_x(p)  # 更新粒子位置
                self._update_p_bestX(p)  # 更新局部最优和全局最优位置
            self.__bestf_val_list.append(self.__bestf_val)  # 记录本次迭代的最优适应度
            self.__W = max(self.__W - 0.2, 0)  # W递减

        return self.__G, self.__bestf_val_list

    def _update_v(self, p):
        # print('\n\n', np.round(p.v, 3))
        update_v = self.__W * p.v + np.random.rand() * self.__C1 * (p.bestX - p.x) + np.random.rand() * self.__C2 * (
                    self.__G - p.x)
        # print(np.round(update_v, 3))
        # ***************************************如果有步长限制,则v应调整为步长的整数倍***********************************
        # 限制v的范围
        update_v[update_v > self.__max_v] = self.__max_v[update_v > self.__max_v]
        update_v[update_v < -self.__max_v] = -self.__max_v[update_v < -self.__max_v]
        p.v = update_v

    def _update_x(self, p):
        update_x = p.x + p.v
        # 限制x的范围
        update_x[update_x < self.__min_x] = self.__min_x[update_x < self.__min_x]
        update_x[update_x > self.__max_x] = self.__max_x[update_x > self.__max_x]
        p.x = update_x

    def _update_p_bestX(self, p):
        # 计算当前粒子的当前适应度
        f_value = self.__fitness_fun(p.x)

        # 更新粒子的历史最优位置和适应度
        if f_value > p.fitnessValue:
            p.fitnessValue = f_value
            p.bestX = p.x

        # 更新群体的历史最优位置和适应度
        if f_value > self.__bestf_val:
            self.__bestf_val = f_value
            self.__G = p.x


if __name__ == '__main__':
    m = PSO(W=1, C1=2, C2=2, dim=3, p_num=20, min_x=[3000, 0, 1], max_x=[5000, 0, 1],
            max_v=[400, 0.2, 0.2], iter_num=20, fitness_fun=get_max_lirun)
    best_x, scores = m.update_all()
    print(best_x)
    print(scores)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
粒子算法是一种优化算法,其原理是通过模拟粒子在搜索空间中的移动来寻找最优解。在Python中,你可以使用第三方库来实现粒子算法的功能。 一个常用的Python库是`pyswarms`,它提供了一个简单而强大的粒子算法实现。你可以使用`pyswarms`库来解决各种优化问题,包括函数最小化、参数优化等。 使用`pyswarms`库进行粒子算法的步骤如下: 1. 导入所需的库和模块。在这个例子中,你需要导入`pyswarms`库以及其他可能用到的辅助库。 2. 定义目标函数。这是你想要优化的函数,可以根据具体问题进行定义。 3. 设置算法的参数。包括粒子数量、迭代次数、惯性权重等。 4. 初始化粒子群。根据问题的维度和粒子数量,随机初始化一群粒子。 5. 运行粒子算法。通过迭代更新粒子的位置和速度,直到达到指定的迭代次数。 6. 获取最优解。从最终的粒子群中选择具有最小值的粒子作为最优解。 下面是一个使用`pyswarms`库来实现粒子算法的简单示例代码: ```python import numpy as #### 引用[.reference_title] - *1* *3* [Python粒子算法(含代码实例)](https://blog.csdn.net/m0_60307882/article/details/123864693)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [粒子算法python(含例程代码与详解)](https://blog.csdn.net/qq_38048756/article/details/108945267)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值