粒子群算法入门及实践

算法描述

粒子群算法是模拟鸟群蜂群的觅食行为的一种算法。

基本思想是通过群体中个体之间的协作和信息共享来寻找最优解。

试着想一下一群鸟在寻找食物,在这个区域中只有一只虫子,所有的鸟都不知道食物在哪。但是它们知道自己的当前位置距离食物有多远,同时它们知道离食物最近的鸟的位置。想一下这时候会发生什么?

鸟A:哈哈哈原来虫子离我最近!
鸟B,C,D:我得赶紧往 A 那里过去看看!

同时各只鸟在位置不停变化时候离食物的距离也不断变化,所以一定有过离食物最近的位置,这也是它们的一个参考。

鸟某某:我刚刚的位置好像靠近了食物,我得往那里靠近!

综上,影响鸟的运动状态变化有下面两个因素:

  • 离食物最近的鸟的位置
  • 自己之前达到过的离食物最近的位置

而鸟每次的位置变化除了考虑上面两个因素还有一个因素: 惯性!

所以考虑这三个因素,位置变化量 v 的公式如下:

可以预见的是,经过不断的调整,鸟群会向食物方向聚集,达到目标。

学一个算法最好的方法是找个题,把它写出来

实践

用粒子群算法求下面函数的最大值(注:这次我用 java 写的)


思路

函数的极值用遗传算法来解,主要分成五步

① 初始化位置

② 计算每只鸟的适应度

③ 找到每只鸟自己的极值,以及整个鸟群的极值

④ 计算位置变化量,改变位置

⑤ 重复步骤 2~4 一个较大的次数使得它趋于稳定

位置类

写一个位置类保存粒子的位置以及粒子在该位置的适应度。

    class Posiotion{
        private double x;
        private double y;
        private double f;
        Posiotion(double x,double y){
            this.x=x;
            this.y=y;
        }
        public double getX() {
            return x;
        }

        public double getY() {
            return y;
        }

        public double getF() {
            return f;
        }

        public void setF(double f) {
            this.f = f;
        }

        public void setX(double x) {
            this.x = x;
        }

        public void setY(double y) {
            this.y = y;
        }

        public String toString(){
            return " x: "+x+" y: "+y+" f: "+f;
        }
    }

适应函数

很好理解,就是把 x,y 带入 f(x,y) 的返回值。

    public void fitnessFunction(){//适应函数
        for(int i=0;i<n;i++){
            double x=p[i].getX();
            double y=p[i].getY();
            if (x<30&&y<30){
                p[i].setF(30*x-y);
            }else if (x<30&&y>=30){
                p[i].setF(30*y-x);
            }else if (x>=30&&y<30){
                p[i].setF(x*x-y/2);
            }else if (x>=30&&y>=30){
                p[i].setF(20*y*y-500*x);
            }
        }
    }

步骤一 初始化位置

随机初始化 n 个粒子,并在范围内随机粒子的位置,计算并保存粒子的适应度。

注意,这里 n 不能太小,太小可能位置变化会限定在一个范围内而一直找不到最优值。

public void init(){ //初始化
        p=new Posiotion[n];
        v=new Posiotion[n];
        pbest=new Posiotion[n];
        gbest=new Posiotion(0.0,0.0);
        /***
         * 初始化
         */
        for(int i=0;i<n;i++){
            p[i]=new Posiotion(Math.random()*60,Math.random()*60);
            v[i]=new Posiotion(Math.random()*vmax,Math.random()*vmax);
        }
        fitnessFunction();
        //初始化当前个体极值,并找到群体极值
        gbest.setF(Integer.MIN_VALUE);
        for(int i=0;i<n;i++){
            pbest[i]=p[i];
            if(p[i].getF()>gbest.getF()){
                gbest=p[i];
                gbest.setF(p[i].getF());
            }
        }
        System.out.println("start gbest:"+gbest);
    }

步骤二 计算每只鸟的适应度

调用方法就好了

fitnessFunction();

步骤三 找到每只鸟自己的极值,以及整个鸟群的极值

            for (int j=0;j<n;j++){
                if (pbest[j].getF()<p[j].getF()){
                    pbest[j]=p[j];
                }
                if(p[j].getF()>gbest.getF()){
                    gbest=p[j];
                    gbest.setF(p[j].getF());
                }
            }

步骤四 计算位置变化量,改变位置

用上面说的公式算出位置变化量,并且改变位置。

同时由于 速度 v 以及 位置 x,y 是有范围的,我加上了范围检测,若超出边界则直接设为边界值。

 for(int j=0;j<n;j++){
        //更新位置和速度
        double vx=w*v[j].getX()+c1*Math.random()*(pbest[j].getX()-p[j].getX())+c2*Math.random()*(gbest.getX()-p[j].getX());
        double vy=w*v[j].getY()+c1*Math.random()*(pbest[j].getY()-p[j].getY())+c2*Math.random()*(gbest.getY()-p[j].getY());
        if (vx>vmax) vx=vmax;
        if (vy>vmax) vy=vmax;
//                System.out.println("======"+(i+1)+"======vx:"+vx);
        v[j]=new Posiotion(vx,vy);
//                System.out.println("======"+(i+1)+"======v[j]:"+v[j]);
        p[j].setX(p[j].getX()+v[j].getX());
        p[j].setY(p[j].getY()+v[j].getY());
        //越界判断
        if(p[j].getX()>=60) p[j].setX(59.9);
        if(p[j].getX()<=0) p[j].setX(0.1);
        if(p[j].getY()>=60) p[j].setY(59.9);
        if(p[j].getY()<=0) p[j].setY(0.1);
        }

步骤五 重复步骤 2~4 一个较大的次数使得它趋于稳定

用 for 循环完成想要的迭代次数,这里我设定 max =10000

 for(int i=0;i<max;i++)

结果

代码地址

Github

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

推荐阅读更多精彩内容