/*************************************************************************
* Project: Library of Evolutionary Algoriths
*************************************************************************
* Author: Changhe Li & Ming Yang
* Email: changhe.lw@google.com Or yangming0702@gmail.com
* Language: C++
*************************************************************************
*  This file is part of EAlib. This library is free software;
*  you can redistribute it and/or modify it under the terms of the
*  GNU General Public License as published by the Free Software
*  Foundation; either version 2, or (at your option) any later version.
*************************************************************************/
// Created: 21 September 2011
// Last modified:
#include "SPSOGBest.h"
#include "../../../PerformanceMeasure/PerformSingleObj.h"
#ifdef DEMON_EALIB
#include "../../../buffer/buffer.h"
#endif
SPSOGBest::SPSOGBest()
{
    //ctor
}
SPSOGBest::SPSOGBest(SPSOGBest & s):Swarm<Particle>(s){

}
SPSOGBest::~SPSOGBest()
{

}
SPSOGBest & SPSOGBest::operator=(SPSOGBest &s){
    if(this==&s) return *this;

    Swarm<Particle>::operator=(s);

    return *this;

}
SPSOGBest::SPSOGBest(int rPopsize,bool mode):Swarm<Particle>(rPopsize,mode){
	setID(ALG_SPSO);
    strcpy(ma_name,"SPSO_GBEST");

    m_algPar<<"Population size: "<<m_popsize;
}


int SPSOGBest::evolve(){
	//gbest model
    m_evoNum++;
	int r_flag=-1;
	for(int i=0;i<m_popsize;i++){
		mp_pop[i].move(mp_pop[i].m_pbest,m_best,m_W,m_C1,m_C2);

		if(mp_pop[i].m_pself>mp_pop[i].m_pbest){
			mp_pop[i].m_pbest=mp_pop[i].m_pself;

			if(mp_pop[i].m_pself>m_best) {
				m_best=mp_pop[i].m_pself;
			}
		}

		if(gIsTerminate()) 	break;
		if(gIsDynamicAlg()&&Global::gp_problem->getEvaluations()%(dynamic_cast<DynamicProblem*>(Global::gp_problem)->getChangeFre())==0){
			if(dynamic_cast<DynamicProblem*> (Global::gp_problem)->getFlagDimensionChange()){
                if(dynamic_cast<DynamicProblem*> (Global::gp_problem)->getDirDimensionChange()==true)  increaseDimensionAll();
                else decreaseDimensionAll();
                {r_flag=2; break;}
			}
			this->updateMemoryAll();
			{r_flag=1; break;}  // non-dimensinal change
		}

	}
	if(r_flag==-1)	return 0;
	else return r_flag;

}

int SPSOGBest::run(){
    while(!gIsTerminate()){
        //cout<<Global::g_runIdx<<" "<<m_best.getObj()<<endl;
		#ifdef DEMON_EALIB
		Buffer<Particle>::updateBuffer(this);
#endif
        evolve();
    }
	#ifdef DEMON_EALIB
	Buffer<Particle>::updateBuffer(this);
#endif
        return 0;
}
