/*************************************************************************
* 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 "DEIndividual.h"


DEIndividual::DEIndividual():Individual()
{
    //ctor
}

DEIndividual::~DEIndividual()
{
    //dtor
}

DEIndividual::DEIndividual( DEIndividual &p):Individual(p){
	m_pv=p.m_pv;
	m_pu=p.m_pu;
	m_flag=p.m_flag;

}
DEIndividual & DEIndividual::operator=(DEIndividual &rhs){
 if (this == &rhs) return *this; // handle self assignment
    //assignment operator
    Individual::operator=(rhs);

	m_pv=rhs.m_pv;
	m_pu=rhs.m_pu;
	m_flag=rhs.m_flag;
	return *this;
}
void DEIndividual::initialize(bool mode){

    Individual::initialize(-1,-1,mode);
	m_pv=m_pself;
	m_pu=m_pself;
}
void DEIndividual::initialize(const int ridex,const int rid,bool mode){
	Individual::initialize(ridex,rid,mode);

    m_pv=m_pself;
	m_pu=m_pself;
}

void DEIndividual::initialize( Chromosome &p,const int idex,const int id){

	Individual::initialize(p,idex,id);

    m_pv=m_pself;
	m_pu=m_pself;
}
void DEIndividual::initialize(int rIdx,int rID,PopInitMethod rMethod, int rPopsize,bool mode ){
	Individual::initialize(rIdx,rID,rMethod,rPopsize,mode);
	m_pv=m_pself;
	m_pu=m_pself;
}
void DEIndividual::initialize(Chromosome &p,double radius, const int ridex,const int rid,bool mode){
	Individual::initialize(p,radius,ridex, rid,mode);
    m_pv=m_pself;
	m_pu=m_pself;
}
void DEIndividual::mutate( float F, Chromosome *r1,  Chromosome *r2,  Chromosome *r3, Chromosome *r4,  Chromosome *r5){

	double l,u;
	for(int i=0;i<Global::g_dimNumber;i++){
		Global::gp_problem->getSearchRange(l,u,i);
		m_pv.getGene<double>(i)=r1->getGene<double>(i)+F*(r2->getGene<double>(i)-r3->getGene<double>(i));
		if(r4&&r5) m_pv.getGene<double>(i)+=F*(r4->getGene<double>(i)-r5->getGene<double>(i));

		if(m_pv.getGene<double>(i)>u){
			m_pv.getGene<double>(i)=(r1->getGene<double>(i)+u)/2;
		} else if(m_pv.getGene<double>(i)<l) {
			m_pv.getGene<double>(i)=(r1->getGene<double>(i)+l)/2;
		}

	}
}
void DEIndividual::recombine(float CR){
	int I=gRandInt(0,Global::g_dimNumber);

	for(int i=0;i<Global::g_dimNumber;i++){
		double p=Global::gp_uniformAlg->Next();
		if(p<=CR||i==I)     m_pu.getGene<double>(i)=m_pv.getGene<double>(i);
		else m_pu.getGene<double>(i)=m_pself.getGene<double>(i);
	}

}
void DEIndividual::select(){
    m_pu.evaluate();
    if(m_pu>m_pself) m_pself=m_pu;

}
void DEIndividual::increaseDimension(){
    Individual::increaseDimension();
	m_pv.increaseDimension();
	m_pu.increaseDimension();
}
void DEIndividual::decreaseDimension(){
	Individual::decreaseDimension();
    m_pv.decreaseDimension();
	m_pu.decreaseDimension();
}


