非经典优化算法总结(二)

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值