Cooperatively Coevolving Particle Swarms for Large Scale Optimization

Abstract

 

ccpso2算法是ccpso算法的改进,它吸纳了后者 对相关变量(effectivevariable) 采用的random grouping 技术。

 

在多峰复杂优化问题上,ccpso2算法的性能要明显优于sep-CMA-ES 、two existing PSO algorithms、cooperativecoevolving differetial evolution algorithm 等 目前最先进的优化算法。即使,它在单峰问题的表现上不尽如人意。

 

 

Ⅰ. Introduction

         PSO是一种求优化问题满意解的近似算法。然而,它会陷入维度灾难。能求解髙维度优化问题的算法很稀有。

        

         Potter和 Jong 提出了 CCEA 算法(CC:协同演化),采用分治的算法对变量进行decomposite。各组迭代求出最优解后再行组合。每个子分量为一维但是,在解不可分问题 (存在大量相关变量) 的时候,表现较差。

        

         基于CC模型,Van denBergh 和 Engelbrecht 提出了两个模型:CPSO-Sk ,CPSO-Hk。然而,这两个模型只被用于解决30-190维的低维问题。

        

         Yang在他的论文中提出了一个decomposite的技术:random grouping。相关变量更有几率被放在同一个分组当中更新。

         有人提出一种adaptive weighting的方案对解进行微调。

        

         ccpso算法吸纳了 ① random grouping adaptive weighting 的思想。主要用于解决高维不可分问题,能精确到1000维。

        

         作者的研究表明,相对于①,②简直是鸡肋。结合其他,提出ccpso2。

 

         ccpso2 与 ccpso算法的区别:

        

新的模型:

①    使用柯西-高斯分布 在 局部最优 和 邻域最优 内取样。

②    使用环形拓扑结构。

③    使用新方法更新 局部最优 和 全局最优。

④    抛弃adaptive weighting

⑤    运行时动态确定每一分组的大小。

⑥    将ccpso2与sep-CMA-ES,two existing PSO 与 CC DE进行比较。

⑦    函数优化问题扩展到 2000

 

优点:

①    “柯西-高斯分布”+“ 环形拓扑结构” 提升 搜索能力

②    不必认为指定分组大小,由自适应函数指定。

 

Ⅱ.Cooperative coevolution

 

CCGA

Potter 和 Jong 提出的是:CCGA算法,基于GA。 先后创建了2个模型:CCGA1、CCGA2。

CCGA1在可分问题上表现比 GA好,但不可分问题上较差

CCGA2表现均比GA好,但是维度只被测试到30维

 

FEP

使用CC模型的FEP算法在 标准测试函数 上可扩展到 1000维,但是对于其中一个不可分问题,表现极差。充分暴露了 “Potter 和 Jong 提出的decomposition” 技巧(每个子分量只有一维)的缺陷!

 

CPSO-Sk & CPSO-Hk

         把整个变量分成k部分,每部分不一定是一维。

 

 

Random Grouping of Variables

 

CPSO-Sk,在整个循环体中,被分成k个组,每个组s个一维变量。(n = kxs)。很不好!

è 两个相关变量可能始终都不能在一个组中。

 

RandomGrouping:

每个循环中动态分组,如:每一个循环就重新分一次组,(也是分成k个组,每个组s个一维变量)。那么两个相关变量,在50次循环中至少在一个组中一次的几率为:

 

P(x≥1) = p(1) + … +p(50) = 1 –(50,0) [(0.1)^0] * [(1-0.1)^50] = 0.9948

 

提高了解不可分问题的可靠性 !

 

Ⅲ. Particle Swarm Optimization

基本pso算法

cpso算法

 

 

:CPSO-Sk 、CPSO-Hk

 

CPSO-Sk,单纯的分治:一个n维种群 -> k个s维种群 (kxs = n)

 

CPSO-Hk,结合CPSO-Sk 和 basic PSO ,轮换交流 全局最优因子。

 

 

Ⅳ. NEW CCPSO2 ALGORITHM

 

A

(1)     基于高斯分布的PSO算法:

单纯使用高斯分布 -> 搜索空间有限

                  使用柯西-高斯 联合分布

(2)     基于环形拓扑 的 局部PSO算法,只知邻域的信息->收敛慢,利于解决多峰函数寻优问题。

 

B

基于柯西和高斯分布的PSO算法

 

高斯分布->降低搜索能力

柯西分布->提升搜索能力

 

C

Dynamically changing group size

 

Pseudocode of CCPSO2:

 

初始化时,手工选定一个k.( s = n/k )

         每迭代一次后,若全局最优被更新了,则继续按这个k值更新下去。否则,在集合S中选择另外一个k进行迭代。 其中,若一个k值,它被用于更新全局最优成功的比重越大,则,在需要选择k值时,它被选择的比重越大。(集合S是需要人为指定的)

 

理论上,使用randomgrouping 技术越频繁,对于解决高维不可分问题越有好处。

interacting variables 相关变量

 

D

CCPSO2

 

 

Ⅴ. EXPERIMENTAL STUDIES

 

...



Codes for CCPSO2  (implemented by myself) are released here:

/******************************************************/
/************** CCPSO2 algorithm    *******************/
/************** cocurrentcy version *******************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h> 
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#include "test_funcs.h"
#include "./CEC2010/Benchmarks.h"
#include "./CEC2010/Header.h"

#define  randf (double)rand()/RAND_MAX

#include "boost/random.hpp"
#include "boost/random/uniform_real.hpp"
#include "boost/random/cauchy_distribution.hpp"
#include "boost/random/normal_distribution.hpp"

#include <iostream>
#include <fstream>
#include <sstream>

using namespace boost;
using namespace std;

// Set generator and C-G distribution
kreutzer1986 engine(randf);

cauchy_distribution <double> distribution1(0,1); 
normal_distribution <double> distribution2(0,1); 

variate_generator<kreutzer1986& , cauchy_distribution<double> > CAUCHY(engine,distribution1);
variate_generator<kreutzer1986& , normal_distribution<double> > GAUSSIAN(engine,distribution2); 

/*******************     Variables   **********************/

const int MAX_DIM = 2000;
const double Xmax = 500;

const int n = 1000;
const int sw = 30;

int k,s;
int func_num;
bool improved;

const int SIZE = 10;
const int iteration_time = 500;

int S[SIZE] = {5,10,20,25,50,100,200,250,500,1000};

// X -> current pos of particle
// Y -> pbest   pos of particle
// N -> lbest   pos of particle
// G -> gbest pos of D-dimension swarm

double X[sw][n];
double Y[sw][n];
double N[sw][n];
double G[n];

// array used for shuffle
int list[MAX_DIM];

// functions:
void   init          	  ();
int    select             ();
void   shuffle       	  ();
void   fly                ();
void   updatePOS          ();
void   updateN            (int,int,int);
void   updateLbest        (int,int);
void   check         	  (int par_inde,int begin_col,int end_col);
double func        	  (int func_number , int dim , double * x);
double Simple      	  (int dim , double* x);
void   assign1            (double*,double*,int,int);
void   assign2            (double[][n],double*,int,int,int);
void   assign3            (double[][n],double[][n],int,int,int);
void   assign4            (double[][n],double[][n],int,int,int,int);

/******************  Function implementation  ********************/

void init() {
    for(int i = 0 ; i < n ; i ++)
        list[i] = i;
    double interval = 2*Xmax;	
	for(int i = 0 ; i < sw ; i ++)
	{
		for(int j = 0 ; j < n ; j ++)
		{
			X[i][j] = -Xmax + interval * randf;
			N[i][j] = Y[i][j] = X[i][j];
		}
	}
        assign2(X,G,0,0,n-1);
}

// valid inde range: 0 ~ SIZE-1

int select() {
	int inde =  int(rand()%SIZE);
	return S[inde];
}

void check(int par_inde , int begin_col , int end_col) {
	for(int j = begin_col ; j <= end_col ; j ++)
	{
		if(X[par_inde][j] > Xmax)
			X[par_inde][j] = Xmax;
		if(X[par_inde][j] < -Xmax)
			X[par_inde][j] = -Xmax;
	}
}

double Simple(int dim , double* x) {
         double Sum = 0;
         for(int i = 1 ; i <= dim ;  i ++) {
                 Sum += -1 * x[i] * sin(sqrt(fabs(x[i])));
         }
         return Sum; 
}

double func(int func_number , int dim , double * x) {
        switch(func_number){
                case 1: return Simple(dim,x);
                        break;
                default:
                        printf("Error : Function number out of range\n");
                        exit(0);
                        break;
        }
}

// randomly change the matrix use algorithm --- shuffle-fisher yates
double tmp_store[sw][n];

void shuffle() { 
    int i,j;
    int fr = 0, to = n-1;
    for(i = fr ; i <= to ; i ++)
    {
            int select = int(i+ (to-i+1) * randf);
            int tmp = list[select];
            list[select] = list[i];
            list[i] = tmp;
    }
       // X
    for( i = 0 ; i < sw ; i ++)
         for( j = 0 ; j < n; j ++)
                 tmp_store[i][j] = X[i][list[j]];
    for( i = 0 ; i < sw ; i ++)
         for( j  = 0 ; j < n ; j ++)
                 X[i][j] = tmp_store[i][j];
    // Y
    for( i = 0 ; i < sw ; i ++)
         for( j = 0 ; j < n; j ++)
                 tmp_store[i][j] = Y[i][list[j]];
    for( i = 0  ; i < sw ; i ++)
         for( j  = 0 ; j < n ; j ++)
                 Y[i][j] = tmp_store[i][j];
    // G
    for( j = 0 ; j < n ; j ++)
         tmp_store[0][j] = G[list[j]];
    for( j = 0 ; j < n ; j ++)
        G[j] = tmp_store[0][j]; 
    // N
    for( i = 0 ; i < sw ; i ++)
         for( j = 0 ; j < n ; j ++)
                 tmp_store[i][j] = N[i][list[j]];
    for( i = 0 ; i < sw ; i ++)
         for( j = 0 ; j < n ; j ++)
                 N[i][j] = tmp_store[i][j];
}

// both 1-dimension arrays
void assign1(double * source , double * dest , int fr , int to ) {   
        for(int i = fr ; i <= to ; i ++)
                dest[i] = source[i];
}

// 1-dimension array and 2-dimension array
void assign2(double source[][n] ,double* dest , int k , int fr , int to ) {
        for(int i = fr ; i <= to ; i ++)
                dest[i] = source[k][i];
}

// both 2-dimension arrays
void assign3(double source[][n] , double dest[][n] , int k , int fr , int to) {
        for(int i = fr ; i <= to ; i ++)
                dest[k][i] = source[k][i];
}

void assign4(double source[][n] , double dest[][n] , int source_row , int dest_row , int fr , int to) {
        for(int i = fr ; i <= to ; i ++)
                dest[dest_row][i] = source[source_row][i];
}

// particles fly
//void fly(Benchmarks *fp) {
void fly() {
    int fr,to; 
    
    double tmp1[n];
    double tmp2[n];

    for(int j = 1 ; j <= k ; j ++)
    {
        //update and record the best particle of the jth swarm
        int inde = -1;
        double min_f = func(func_num,n,G);
        //double min_f = fp->compute(G);
        
        fr = (j-1)*s ; to = fr + s - 1;
        
        double re1,re2;
    
        for(int i = 0 ; i < sw ; i ++)
        {
            assign1(G,tmp1,0,n-1);
            assign1(G,tmp2,0,n-1);

            assign2(X,tmp1,k,fr,to);
            assign2(Y,tmp2,k,fr,to);

            double f1 = func(func_num,n,tmp1);
            double f2 = func(func_num,n,tmp2);
            //double f1 = fp->compute(tmp1);
            //double f2 = fp->compute(tmp2);

            if(f1 < f2)
            {
                assign3(X,Y,k,fr,to);
                if(f1 < min_f)
                {
                    min_f = f1;
                    inde = k;
                    improved = 1;
                }
            }
        }
	    
        //update the gbest of the swarm
        if(inde != -1)
        {   
            assign2(X,G,inde,fr,to);
            improved = 1;    
        }
       
        // update the lbest of the swarm
        //updateLbest(fr,to,fp);
        updateLbest(fr,to);
    }
}


void updatePOS() {
    int fr,to;
    for(int j = 1 ; j <= k ; j ++)
    {
        for(int i = 0 ; i < sw ; i ++)
        {
            fr = (j-1)*s; to = fr+s-1;

            // Cauchy
            if(randf <= 0.5)
                for(int t = fr ; t <= to ; t ++)
                    X[i][t] = Y[i][t] + CAUCHY()* fabs(Y[i][t] - N[i][t]);
            
            // Gaussian
            else
                for(int t = fr ; t <= to ; t ++)
                    X[i][t] = N[i][t] + GAUSSIAN()* fabs(Y[i][t] - N[i][t]);
        }
    }
    for(int j = 0 ; j < sw ; j ++)
        check(j,0,n-1);
}

// update the lbest of the particles
//void updateLbest(int fr ,int to, Benchmarks *fp){
void updateLbest(int fr, int to) {
       int i,j,k,p;
       int l_inde, m_inde, r_inde;
       int inde = -1; 
       double tmpL[n];
       double tmpM[n];
       double tmpR[n];
        
       double fL,fM,fR;
       for(k = 0 ; k < sw ; k ++)
       {
               m_inde = k;
               if(m_inde == 0)
               {
                       l_inde = sw-1;
                       r_inde = m_inde + 1;
               }
               else if(m_inde == sw-1)
               {
                       l_inde = m_inde-1;
                       r_inde = 0;
               }
               else
               {
                       l_inde = m_inde-1;
                       r_inde = m_inde+1;
               }
               assign1(G,tmpL,0,n-1);
               assign1(G,tmpM,0,n-1);
               assign1(G,tmpR,0,n-1); 
               
               assign2(Y,tmpL,l_inde,fr,to);
               assign2(Y,tmpM,m_inde,fr,to);
               assign2(Y,tmpR,r_inde,fr,to);
              
               fL = func(func_num,n,tmpL);
               fM = func(func_num,n,tmpM);
               fR = func(func_num,n,tmpR);
               //fL = fp->compute(tmpL);
               //fM = fp->compute(tmpM);
               //fR = fp->compute(tmpR);

               if(fL < fM)
               {
                       inde = l_inde;
                       if(fL > fR)
                               inde = r_inde;
               }
               else
               {
                       inde = m_inde;
                       if(fM > fR)
                               inde = r_inde;
               }
               assign4(Y,N,inde,m_inde,fr,to);
       }

}

/*
int main() {
   Benchmarks * fp = NULL;
   generateFuncObj(1);
   srand((unsigned)time(NULL));
   init();
   improved = false;
   func_num = 1;
   for(int t = 0 ; t < iteration_time ; t ++)
   {
        if(improved == false)
        {
               s = select();
               k = n / s;
        }
        shuffle();
        improved = false;
        fly(fp);
        updatePOS();
        printf("%lg\n",func(1,n,G));
        //printf("%lg\n",fp->compute(G));
   }
   return 0;
}
*/

int main() {
    func_num = 1;
    srand((unsigned)time(NULL));
    init();

    improved = false;
    for(int t = 0 ; t < iteration_time ; t ++)
    {
         if(improved == false)
         {
                s = select();
                k = n / s;
         }
         shuffle();
         improved = false;
         fly();
         updatePOS();
         printf("%lg\n",func(1,n,G));
    }
    return 0;
}


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值