Python

粒子群算法(PSO) Python实现

2016-06-30  本文已影响3706人  yiekue

1 原理

粒子群算法是群智能一种,是基于对鸟群觅食行为的研究和模拟而来的。假设在鸟群觅食范围,只在一个地方有食物,所有鸟儿看不到食物(不知道食物的具体位置),但是能闻到食物的味道(能知道食物距离自己位置)。最好的策略就是结合自己的经验在距离鸟群中距离食物最近的区域搜索。

利用粒子群算法解决实际问题本质上就是利用粒子群算法求解函数的最值。因此需要事先把实际问题抽象为一个数学函数,称之为适应度函数。在粒子群算法中,每只鸟都可以看成是问题的一个解,这里我们通常把鸟称之为粒子,每个粒子都拥有:

粒子群算法的过程

PSO流程图
  1. 初始化。包括根据给定的粒子个数,初始化粒子,包括初始化一下的值:
  1. 更新。包括两部分:

上面公式中:i表示粒子编号;t表示时刻,反映在迭代次数上;w是惯性权重,一般设置在0.4左右;c表示学习因子,一般都取值为2;Xpbest表示的是粒子i的经验,也即是粒子i所到过最佳位置;Xgbest代表的是全局最优粒子的位置;r是0到1之间的随机值。

  1. 判断结束条件。结束条件包括最大迭代次数和适应度的阈值。

2 代码

  • 实验环境为python 2.7.11。

首先需要解决的是粒子的存储,我第一反应是利用结构体来存储,但是python并没有相应的数据结构,所以我选择用一个类来表示粒子结构,该类的一个对象就是一个粒子,上代码:

class bird:
    """
    speed:速度
    position:位置
    fit:适应度
    lbestposition:经历的最佳位置
    lbestfit:经历的最佳的适应度值
    """
    def __init__(self, speed, position, fit, lBestPosition, lBestFit):
        self.speed = speed
        self.position = position
        self.fit = fit
        self.lBestFit = lBestPosition
        self.lBestPosition = lPestFit

接下来就是粒子群算法的主干部分,用一个类来封装,代码:

import random

class PSO:
    """
    fitFunc:适应度函数
    birdNum:种群规模
    w:惯性权重
    c1,c2:个体学习因子,社会学习因子
    solutionSpace:解空间,列表类型:[最小值,最大值]
    """
    def __init__(self, fitFunc, birdNum, w, c1, c2, solutionSpace):
        self.fitFunc = fitFunc
        self.w = w
        self.c1 = c1
        self.c2 = c2
        self.birds, self.best = self.initbirds(birdNum, solutionSpace)

    def initbirds(self, size, solutionSpace):
        birds = []
        for i in range(size):
            position = random.uniform(solutionSpace[0], solutionSpace[1])
            speed = 0
            fit = self.fitFunc(position)
            birds.append(bird(speed, position, fit, position, fit))
        best = birds[0]
        for bird in birds:
            if bird.fit > best.fit:
                best = bird
        return birds,best

    def updateBirds(self):
        for bird in self.birds:
            # 更新速度
            bird.speed = self.w * bird.speed + self.c1 * random.random() * (bird.lBestPosition - bird.position) + self.c2 * random.random() * (self.best.position - bird.position)
            # 更新位置
            bird.position = bird.position + bird.speed
            # 跟新适应度
            bird.fit = self.fitFunc(bird.position)
            # 查看是否需要更新经验最优
            if bird.fit > bird.lBestFit:
                bird.lBestFit = bird.fit
                bird.lBestPosition = bird.position

    def solve(self, maxIter):
        # 只考虑了最大迭代次数,如需考虑阈值,添加判断语句就好
        for i in range(maxIter):
            # 更新粒子
            self.updateBirds()
            for bird in self.birds:
                # 查看是否需要更新全局最优
                if bird.fit > self.best.fit:
                    self.best = bird

有了以上代码,只需要自定义适应度函数fitFunc就可以进行求解,但是需要注意的是只适用于求解** 一维问题 **。

上一篇下一篇

猜你喜欢

热点阅读