自话粒子群算法(超简单实例)

2024-05-30 04:08

本文主要是介绍自话粒子群算法(超简单实例),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


简介

    上次在自话遗传算法中提到后期会写两篇关于粒子群算法和蚁群算法的博文,所以这次给大家带来的是我对粒子群的一些理解,并附带一个相当简单的实例去描述这个算法,我会尽力通俗易懂的把整个算法描述一遍,其实粒子群算法的思想也挺简单的,希望我不要反而写复杂了,下面同样引用百度百科的摘要结束简介部分。

    粒子群优化算法(PSO)是一种进化计算技术(evolutionary computation),1995 年由Eberhart 博士和kennedy 博士提出,源于对鸟群捕食的行为研究 。该算法最初是受到飞鸟集群活动的规律性启发,进而利用群体智能建立的一个简化模型。粒子群算法在对动物集群活动行为观察基础上,利用群体中的个体对信息的共享使整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得最优解。

基本思想

    正如简介所描述的那样,粒子群算法是模拟群体智能所建立起来的一种优化算法,像后面我向大家介绍的蚁群算法也属于这类算法,粒子群算法可以用鸟类在一个空间内随机觅食为例,所有的鸟都不知道食物具体在哪里,但是他们知道大概距离多远,最简单有效的方法就是搜寻目前离食物最近的鸟的周围区域。

    所以,粒子群算法就是把鸟看成一个个粒子,并且他们拥有位置和速度这两个属性,然后根据自身已经找到的离食物最近的解和参考整个共享于整个集群中找到的最近的解去改变自己的飞行方向,最后我们会发现,整个集群大致向同一个地方聚集。而这个地方是离食物最近的区域,条件好的话就会找到食物。这就是粒子群算法,很好理解。

算法描述

    所以,我们需要一个pbest来记录个体搜索到的最优解,用gbest来记录整个群体在一次迭代中搜索到的最优解。速度和粒子位置的更新公式如下:

 

          v[i] = w * v[i] + c1 * rand() * (pbest[i] - present[i]) + c2 * rand() * (gbest - present[i])    

          present[i] = present[i] + v[i]                                                                                                          

    其中v[i]代表第i个粒子的速度,w代表惯性权值,c1c2表示学习参数,rand()表示在0-1之间的随机数,pbest[i]代表第i个粒子搜索到的最优值,gbest代表整个集群搜索到的最优值,present[i]代表第i个粒子的当前位置。

    我这里打了一个求解y=-x*(x-1) [-2,2]上最大值的粒子群算法,选用这个简单的例子主要是能让大家清楚的看到效果和粒子的运动方向,也方便理解我想说的一些观点。代码如下:

 

复制代码
 1 /***
 2  *  计算y=-x(x-1)的最大值
 3  *  取值范围x--[-2,2]
 4  * @author BreezeDust
 5  *
 6  */
 7 public class PSOTest {
 8     int n=2; //粒子个数,这里为了方便演示,我们只取两个,观察其运动方向
 9     double[] y;
10     double[] x;
11     double[] v;
12     double c1=2;
13     double c2=2;
14     double pbest[];
15     double gbest;
16     double vmax=0.1;
17     public void fitnessFunction(){//适应函数
18         for(int i=0;i<n;i++){
19             y[i]=-1*x[i]*(x[i]-2);
20         }
21     }
22     public void init(){ //初始化
23         x=new double[n];
24         v=new double[n];
25         y=new double[n];
26         pbest=new double[n];
27         /***
28          * 本来是应该随机产生的,为了方便演示,我这里手动随机落两个点,分别落在最大值两边
29          */
30         x[0]=-0.5;
31         x[1]=2.6;
32         v[0]=0.01;
33         v[1]=0.02;
34         fitnessFunction();
35         //初始化当前个体极值,并找到群体极值
36         for(int i=0;i<n;i++){
37             pbest[i]=y[i];
38             if(y[i]>gbest) gbest=y[i];
39         }
40         System.out.println("start gbest:"+gbest);
41     }
42     public double getMAX(double a,double b){
43         return a>b?a:b;
44     }
45     //粒子群算法
46     public void PSO(int max){
47         for(int i=0;i<max;i++){
48             double w=0.4;
49             for(int j=0;j<n;j++){
50                 //更新位置和速度
51                 v[j]=w*v[j]+c1*Math.random()*(pbest[j]-x[j])+c2*Math.random()*(gbest-x[j]);
52                 if(v[j]>vmax) v[j]=vmax;
53                 x[j]+=v[j];
54                 //越界判断
55                 if(x[j]>2) x[j]=2;
56                 if(x[j]<-2) x[j]=-2;
57                 
58             }
59             fitnessFunction();
60             //更新个体极值和群体极值
61             for(int j=0;j<n;j++){
62                 pbest[j]=getMAX(y[j],pbest[j]);
63                 if(pbest[j]>gbest) gbest=pbest[j];
64                 System.out.println(x[j]+"  "+v[j]);
65             }
66             System.out.println("======"+(i+1)+"======gbest:"+gbest);
67         }
68         
69         
70     }
71     public static void main(String[] args){
72         PSOTest ts=new PSOTest();
73         ts.init();
74         ts.PSO(100);
75     }
76 
77     
78 
79 }
复制代码

 

    输出结果如下:

start gbest:0.0
-0.4  0.1
0.0  -10.751668729351186
======1======gbest:0.0
-0.6822365786740794  -0.2822365786740793
0.0  -5.375834364675593
======2======gbest:0.0
-0.5822365786740794  0.1
0.0  -2.6879171823377965
======3======gbest:0.0
-0.48223657867407943  0.1
-1.3439585911688983  -1.3439585911688983
======4======gbest:0.0
-0.38223657867407945  0.1
-1.2439585911688982  0.1
======5======gbest:0.0
-0.47659030560462123  -0.09435372693054181
-1.143958591168898  0.1
======6======gbest:0.0
-0.37659030560462126  0.1
-1.043958591168898  0.1
======7======gbest:0.0
-0.2765903056046213  0.1
-0.943958591168898  0.1
======8======gbest:0.0
-0.27903394174424034  -0.0024436361396190653
-0.843958591168898  0.1
======9======gbest:0.0
-0.38899022876058803  -0.10995628701634769
-0.7439585911688981  0.1
======10======gbest:0.0
-0.35250959144436234  0.03648063731622572
-0.6439585911688981  0.1
======11======gbest:0.0
........
........
........
........
0.9999990975760489  -1.556071309835406E-6
======98======gbest:1.0
1.0000000029937202  4.411275849326098E-9
1.0000001827158205  1.085139771533034E-6
======99======gbest:1.0
0.9999999993730952  -3.6206249540206964E-9
1.0000001197322141  -6.298360633295484E-8
======100======gbest:1.0

    我们可以从打印的数据看出来,刚开始x[0]和x[1]分散在最大值两边,然后x[0]和x[1]逐渐聚集到1的周围,这里,我们已经收敛到x=1这个地方了,这正是我们要求的最大值,其最大值为1,下面是图解过程。

    1.初始状态

    2.第二次x[1]向左边移动了

   3.最后,两点聚集在1上,上面多个圈是他们聚集的过程,可以看出来,聚集过程是个越来越密集的过程。

 

 

最后

    粒子群算法,相对于我上次提到的遗传算法而言编码要简单很多,同样属于进化算法,但是粒子群算法并没有像遗传算法那样有选择交叉变异这样的过程,而更多的是体现在追踪单个粒子和共享集体最优信息来实现向最优空间搜索的形式,但是正由于它不同于遗传算法那样去忽略个体的一些内在联系,所以往往会陷入局部最优,所以,在粒子群算法中加入像遗传算法中的变异或者模拟退火等,可以跳过这个局部最优解

    而惯性权值对于函数收敛速度和是否收敛有很大的决定作用,两个学习参数c1,c2的制定也同等重要,但是即使这样,它也没有遗传算法中会有多个参数去维护,所以整个算法就那一个公式就行了,相当的清晰。在遗传算法中的信息的共享是染色体互相之间通过交叉共享,所以在搜索移动过程显得平均缓慢,而粒子群算法是根据gbest来决定整个集群的单向移动,所以相对遗传算法,它更快的收敛

    这不由得让我想到了熵这个概念,在诸如我们社会甚至宇宙这样复杂的系统,我们都处于一个无序的状态,属于熵增状态,像粒子群,遗传算法,对群体的研究,体现的智能不就是在这个无序的系统提供有序的能量,然后它就逐渐有序了。对于智能,我想我有更深的体会了。这段话属于发神经,不作参考。

这篇关于自话粒子群算法(超简单实例)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015538

相关文章

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

swiper实例

大家好,我是燐子,今天给大家带来swiper实例   微信小程序中的 swiper 组件是一种用于创建滑动视图的容器组件,常用于实现图片轮播、广告展示等效果。它通过一系列的子组件 swiper-item 来定义滑动视图的每一个页面。 基本用法   以下是一个简单的 swiper 示例代码:   WXML(页面结构) <swiper autoplay="true" interval="3

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

回调的简单理解

之前一直不太明白回调的用法,现在简单的理解下 就按这张slidingmenu来说,主界面为Activity界面,而旁边的菜单为fragment界面。1.现在通过主界面的slidingmenu按钮来点开旁边的菜单功能并且选中”区县“选项(到这里就可以理解为A类调用B类里面的c方法)。2.通过触发“区县”的选项使得主界面跳转到“区县”相关的新闻列表界面中(到这里就可以理解为B类调用A类中的d方法

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用

自制的浏览器主页,可以是最简单的桌面应用,可以把它当成备忘录桌面应用。如果你看不懂,请留言。 完整代码: <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><ti

以canvas方式绘制粒子背景效果,感觉还可以

这个是看到项目中别人写好的,感觉这种写法效果还可以,就存留记录下 就是这种的背景效果。如果想改背景颜色可以通过canvas.js文件中的fillStyle值改。 附上demo下载地址。 https://download.csdn.net/download/u012138137/11249872

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

大林 PID 算法

Dahlin PID算法是一种用于控制和调节系统的比例积分延迟算法。以下是一个简单的C语言实现示例: #include <stdio.h>// DALIN PID 结构体定义typedef struct {float SetPoint; // 设定点float Proportion; // 比例float Integral; // 积分float Derivative; // 微分flo