/*************************************************************************
* 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 Oct. 2011
// Last modified:
#include "CRDE.h"

CRDE::CRDE(const int rSize):DEPopulation<DEIndividual>(rSize)
{
    //ctor

	setID(ALG_CRDE);
    strcpy(ma_name,"crowding-based differential evolution");
    setParmeter(0.9,0.5);

}

CRDE::~CRDE()
{
    //dtor

}

int CRDE::evolve(){

    if(this->m_popsize<4){
        return 0;
    }

    for(int i=0;i<this->m_popsize;i++){
        mutate(i);
        this->mp_pop[i].recombine(m_CR);
    }
	for(int i=0;i<this->m_popsize;i++){

		this->mp_pop[i].m_pu.evaluate();
        int idx1=0,idx2=0;
		bool flag=true;
		if(flag){
			this->findNearestPair(idx1,idx2);
			flag=false;
			if(this->mp_pop[i].m_pu>this->mp_pop[idx1].m_pself){
				this->mp_pop[idx1].m_pself=this->mp_pop[i].m_pu;
				flag=true;
			}else if(this->mp_pop[i].m_pu>this->mp_pop[idx2].m_pself){
				this->mp_pop[idx2].m_pself=this->mp_pop[i].m_pu;
				flag=true;
			}
		}
        if(this->mp_pop[i].m_pu>(this->m_best)) {
			this->m_best=this->mp_pop[i].m_pu;
        }
		if(gIsTerminate()) return 0;
		if(gIsDynamicAlg()&&Global::gp_problem->getEvaluations()%(dynamic_cast<DynamicProblem*>(Global::gp_problem)->getChangeFre())==0){
			if(dynamic_cast<DynamicProblem*> (Global::gp_problem)->getFlagDimensionChange()) return 2;  // dimensional change
			this->updateMemoryAll();
			return 1;  // non-dimensinal change
		}
	}

    this->m_evoNum++;
	return 0;
}
int CRDE::run(){
     while(!gIsTerminate()){
        //cout<<Global::g_runIdx<<" "<<m_best.getObj()<<endl;
        evolve();
    }
    return 0;
}


