粒子群算法(PSO) Python实现

1 原理

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

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

  • 位置,可以理解函数的自变量的值;
  • 经验,也即是自身经历过的距离食物最近的位置;
  • 速度,可以理解为自变量的变化值;
  • 适应度,距离食物的位置,也就是函数值。

粒子群算法的过程

PSO流程图
  1. 初始化。包括根据给定的粒子个数,初始化粒子,包括初始化一下的值:
  • 位置:解空间内的随机值;
  • 经验:与初始位置相等;
  • 速度:0;
  • 适应度:根据位置,带入适应度函数,得到适应度值。
  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就可以进行求解,但是需要注意的是只适用于求解** 一维问题 **。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 姓名:彭帅 学号:17021210850 【嵌牛导读】:蚁群算法(ACO)是受自然界中蚂蚁搜索食物行为的启发,是一...
    重露成涓滴阅读 38,544评论 0 8
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,424评论 25 707
  • 王者荣耀辣鸡队友太坑,哎哎
    别和我比阅读 244评论 0 0
  • 前几日去打针,排队等候时,身边一位30岁模样的壮汉说,这个针痛得很。 闲来无事,我接话说,我之前打过的,的确痛,但...
    纯银V阅读 3,717评论 0 54
  • 【石丰画语】不画闲情逸致,不画风花雪月,不画莺歌燕舞,不画表象魅惑;只画生命滴血,只画人性局限,只画我心飞翔,只画...
    石丰当代艺术阅读 1,118评论 5 4