1、 粒子群优化算法
1.1 算法背景介绍
粒子群优化算法源于对鸟群觅食行为的研究,是仿生智能算法的一种。在鸟群的飞行过程中时常有出现转向,散开,聚集等现象,其行为不可预测,但是鸟群整体却保持着一致性,这是由于鸟群整体拥有着一种社会信息共享机制,即可以把一些关于其他成员的信息进行传递,因此其中的个体可以通过这些有效信息不断作出调整。这就是粒子群优化算法的由来。
1.2 算法基本思想
粒子群优化算法和遗传算法一样,都是需要初始化一个种群,即一组初始解。那么对于其中的每一个解我们均用m维向量进行表示,即
X
i
=
(
x
1
,
x
2
,
x
3
,
…
,
x
m
)
X_i=(x_1,x_2,x_3,\dots,x_m)
Xi=(x1,x2,x3,…,xm)
同时给予其一个初始速度
V
i
V_i
Vi,这也是一个m维向量
V
i
=
(
v
1
,
v
2
,
v
3
,
…
,
v
m
)
V_i=(v_1,v_2,v_3,\dots,v_m)
Vi=(v1,v2,v3,…,vm)
我们记在搜索过程中个体的最优解为
p
i
(
t
)
p_i(t)
pi(t) ,群体的最优解为
p
g
(
t
)
p_g(t)
pg(t)。
那么粒子本身会根据当前位置所对应的速度在
R
m
R^m
Rm 空间中运动,但是速度会被几个因素影响,而这个影响也就是粒子群算法能够实现优化的本质原因。
影响的因素有以下三个:1、惯性系数 2、个体加速系数 3、群体加速系数
三个系数分别影响了粒子对原始速度的继承能力,个体极值点对个体速度的影响因子,以及群体极值点对个体速度的影响因子。
具体形式如下:
v
i
(
t
+
1
)
=
v
i
(
t
)
+
c
1
r
1
(
p
i
(
t
)
−
x
i
(
t
)
)
+
c
2
r
2
(
p
g
(
t
)
−
x
i
(
t
)
)
v_{i}(t+1)=v_i(t)+c_1r_1(p_i(t)-x_i(t))+c_2r_2(p_g(t)-x_i(t))
vi(t+1)=vi(t)+c1r1(pi(t)−xi(t))+c2r2(pg(t)−xi(t))
其中
r
1
r_1
r1,
r
2
r_2
r2是在[0,1]范围内的随机数。
通过调整三个影响因子,我们既可以调高或降低惯性系数,让优化更好的搜索全局最优,或者更快在局部搜索出最优解;也可以通过调整加速系数,平衡个体极值和群体极值点对搜索的影响。
1.3 简单实例
依然选用了之前的函数最值问题作为示例y=x*sin(10*x*pi)+2,x ∈ [ − 1 , 2 ] \isin[-1,2] ∈[−1,2]
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
double func(double x)
{
return x*sin(10*x*3.14159)+2.0;
}
int main()
{
double x[105][105],v[105][105];
double gbest,ibest[105];
int i,j,k;
double w,c,d;
srand(time(0));
w=0.9;
c=2;
d=2;
//对粒子群进行初始化
gbest=0;
for (i=1;i<=100;i++)
{
x[i][1]=(rand()%30000-10000.0)/10000.0;
v[i][1]=(rand()%20000-10000.0)/20000.0;
ibest[i]=x[i][1];
if (func(gbest)<func(x[i][1]))
{
gbest=x[i][1];
}
}
//根据自身最优解和集体最优解不断调整搜寻速度,若不符合约束则修正
for (j=2;j<=100;j++)
{
for (i=1;i<=100;i++)
{
v[i][j]=w*v[i][j-1]+rand()%10000/10000.0*c*(gbest-x[i][j-1])+rand()%10000/10000.0*d*(ibest[i]-x[i][j-1]);
//更新粒子速度
if (v[i][j]>0.5)
{
v[i][j]=0.5;
}
if (v[i][j]<-0.5)
{
v[i][j]=-0.5;
}//修正粒子速度
x[i][j]=x[i][j-1]+v[i][j];//调整粒子位置
if (x[i][j]>2)
{
x[i][j]=2;
}
if (x[i][j]<-1)
{
x[i][j]=-1;
}//修正粒子位置
if (func(x[i][j])>func(ibest[i]))
{
ibest[i]=x[i][j];
}
if (func(x[i][j])>gbest)
{
gbest=func(x[i][j]);
}//更新个体最优解和集体最优解
}
}
cout<<gbest<<endl;
return 0;
}
2、 蚁群算法
2.1 算法背景介绍
蚁群算法的思路来源于蚁群觅食规律的研究,研究发现,蚂蚁在觅食过程中会释放一种信息素,而这种信息素会逐步累积并形成正反馈(当路径较短时,信息素会相应变强),从而快速寻找出一条较优的觅食路径。
2.2 算法基本思想
由于蚁群算法具有正反馈特性,因此也出现了通过蚁群算法容易陷入局部最优,快速收敛等一系列特性,因此在设计上需要给予算法跳出局部解的能力。因此整体步骤大致如下:
1、初始化蚁群,规定蚂蚁数量,以及相关的评价函数。
2、在初代蚁群尝试的基础上,更新全体信息素(包括信息素挥发的部分,类似禁忌算法解禁)。根据具体问题确定蚁周模型或是蚁量或蚁密模型。
3、下一批蚂蚁根据上一批的信息素选择路线进一步寻找(此处应设置一定概率寻找新路径,从而获得跳出局部最优的能力)。
4、迭代并记录最优数据。
2.3 简单实例
y=x*sin(10*x*pi)+2,x ∈ [ − 1 , 2 ] \isin[-1,2] ∈[−1,2]
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
double func(double x)
{
return x*sin(10*3.14159*x)+2.0;
}
int main()
{
double a[100],temp[100],info[100],total,sum,p,top;
int i,j,k;
srand(time(0));
top=0;
for (i=1;i<=20;i++)
{
a[i]=(rand()%30000-10000.0)/10000.0;
info[i]=exp(func(a[i]));
if (func(top)<func(a[i]))
{
top=a[i];
}
}//初始化蚁群
for (j=1;j<=100;j++)
{
total=0;
sum=0;
p=rand()%10000/10000.0;
for (i=1;i<=20;i++)
{
total=total+info[i];
}
for (k=1;k<=20;k++)
{
if (rand()%10000/10000.0<=0.5)
{
temp[k]=(rand()%30000-10000.0)/10000.0;
}
else{
for (i=1;i<=20;i++)
{
sum=sum+info[i]/total;
if (p>=sum)
{
temp[k]=a[i] + (rand()%20000-10000.0)/10000.0*0.05;//随机步长
if (temp[k]>2)
{
temp[k]=2;
}
if (temp[k]<-1)
{
temp[k]=-1;
}
break;
}
}
}
}
for (i=1;i<=20;i++)
{
a[i]=temp[i];
info[i]=exp(func(a[i]));
if (func(top)<func(a[i]))
{
top=a[i];
}
}
}
cout<<func(top)<<endl;
return 0;
}