/*************************************************************************
* 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: 11 May 2011
// Last modified:
#include "HybridComp.h"
#include "Sphere.h"
#include "FAckley.h"
#include "FGriewank.h"
#include "FRastrigin.h"
#include "FWeierstrass.h"
#include "FScaffer_F6.h"
#include "FElliptic.h"
#include "FNoncont_Rastrigin.h"
//#include "../../Algorithms/DE/Ming_DE/Ming_Global.h"


HybridComp::HybridComp(){
    //ctor
    mpp_f=0;
    mp_convergeSeverity=0;
    mp_stretchSeverity=0;
    mp_weight=0;
    mp_fit=0;
    mp_height=0;
    mp_fmax=0;

}
HybridComp::HybridComp(const int rId, const int rDimNumber,  char *rName):BenchmarkFunction(rId,rDimNumber,rName){

    allocateMemory(m_dimNumber,m_numFuncs);
    if(m_id == RH_Com_noBounds_F25_CEC05)  {
          setSearchRange<double>(2, 5);
         for(int i=0; i<m_dimNumber; ++i)   ((Boundary<double> *)m_searchRange[i])->m_flag = false;
     }
     else  setSearchRange<double>(-5,5);
    m_heightNormalizeSeverity=2000.;
    initialize();
}
HybridComp::~HybridComp(){
    //dtor
    freeMemory();
}
void HybridComp::allocateMemory(const int rNumDim, const int rNumFuc){
    mpp_f=new BenchmarkFunction*[rNumFuc];
    for(int i=0;i<rNumFuc;i++) mpp_f[i]=0;

    mp_convergeSeverity=new double [rNumFuc];
    mp_stretchSeverity=new double [rNumFuc];
    mp_weight=new double [rNumFuc];
    mp_fit=new double [rNumFuc];
    mp_height=new double[rNumFuc];
    mp_fmax=new double[rNumFuc];

}
void HybridComp::freeMemory(){
    if(m_numFuncs>0){
         for(int i=0;i<m_numFuncs;i++){
            if(mpp_f[i]) delete mpp_f[i];
         }
        delete [] mpp_f;

        delete []mp_convergeSeverity;
        delete [] mp_stretchSeverity;
        delete []mp_weight;
        delete [] mp_height;
        delete []mp_fit;
        delete [] mp_fmax;

        mpp_f=0;
        mp_convergeSeverity=0;
        mp_stretchSeverity=0;
        mp_weight=0;
        mp_fit=0;
        mp_height=0;
    }


}
void HybridComp::setFunction(ProblemTag * rId, char *rFucs[]){
    BasicFunc f;
    switch(m_id) {
          case RH_Com_F21_CEC05: case RH_Com_HighConNumMatrix_F22_CEC05: case Noncont_RH_Com_F23_CEC05:
               f["Expanded_Scaffer_F6_CEC05"]=&createFunction<FScaffer_F6>;
               f["Rastrigin"]=&createFunction<FRastrigin>;
               f["Griewank_Rosenbrock_F13_CEC05"]=&createFunction<FGriewank>;
               f["Weierstrass"]=&createFunction<FWeierstrass>;
               f["Griewank"]=&createFunction<FGriewank>;
               break;
          case RH_Com_F24_CEC05:  case RH_Com_noBounds_F25_CEC05:
               f["Weierstrass"]=&createFunction<FWeierstrass>;
               f["Expanded_Scaffer_F6_CEC05"]=&createFunction<FScaffer_F6>;
               f["Griewank_Rosenbrock_F13_CEC05"]=&createFunction<FGriewank>;
               f["Ackley"]=&createFunction<FAckley>;
               f["Rastrigin"]=&createFunction<FRastrigin>;
               f["Griewank"]=&createFunction<FGriewank>;
               f["Noncont_Expanded_Scaffer_F6_CEC05"]=&createFunction<FScaffer_F6>;
               f["Noncont_Rastrigin"]=&createFunction<FNoncont_Rastrigin>;
               f["Elliptic"]=&createFunction<FElliptic>;
               f["Sphere_Noisy_CEC05"]=&createFunction<FSphere>;
               break;
          default:
               f["Sphere"]=&createFunction<FSphere>;
               f["Rastrigin"]=&createFunction<FRastrigin>;
               f["Weierstrass"]=&createFunction<FWeierstrass>;
               f["Griewank"]=&createFunction<FGriewank>;
               f["Ackley"]=&createFunction<FAckley>;
               // f["Scaffer"]=&createFunction<FScaffer>;
              break;
    }

    for(int i=0;i<m_numFuncs;i++){
        mpp_f[i]=dynamic_cast<BenchmarkFunction*>(f[rFucs[i]]((int)rId[i],m_dimNumber,rFucs[i]));
        mpp_f[i]->setBias(0);
    }
    switch(m_id){
        case R_Com:  case H_Com_CEC05: case H_Com_Noisy_CEC05: case RH_Com_F21_CEC05: case Noncont_RH_Com_F23_CEC05:
            for(int i=0;i<m_numFuncs;i++) mpp_f[i]->setConditionNumber(2.);
            break;
        case RH_Com_HighConNumMatrix_F22_CEC05:
            mpp_f[0]->setConditionNumber(10); mpp_f[1]->setConditionNumber(20);
            mpp_f[2]->setConditionNumber(50);mpp_f[3]->setConditionNumber(100);
            mpp_f[4]->setConditionNumber(200);mpp_f[5]->setConditionNumber(1000);
            mpp_f[6]->setConditionNumber(2000);mpp_f[7]->setConditionNumber(3000);
            mpp_f[8]->setConditionNumber(4000);mpp_f[9]->setConditionNumber(5000);
            break;

        case RH_Com_CEC05: case RH_Com_NarrowBasin_CEC05:  case RH_Com_Bound_CEC05:
            mpp_f[0]->setConditionNumber(2); mpp_f[1]->setConditionNumber(3);
            mpp_f[2]->setConditionNumber(2);mpp_f[3]->setConditionNumber(3);
            mpp_f[4]->setConditionNumber(2);mpp_f[5]->setConditionNumber(3);
            mpp_f[6]->setConditionNumber(20);mpp_f[7]->setConditionNumber(30);
            mpp_f[8]->setConditionNumber(200);mpp_f[9]->setConditionNumber(300);
            break;

     case RH_Com_F24_CEC05:  case RH_Com_noBounds_F25_CEC05:
          mpp_f[0]->setConditionNumber(100); mpp_f[1]->setConditionNumber(50);
            mpp_f[2]->setConditionNumber(30);mpp_f[3]->setConditionNumber(10);
            mpp_f[4]->setConditionNumber(5);mpp_f[5]->setConditionNumber(5);
            mpp_f[6]->setConditionNumber(4);mpp_f[7]->setConditionNumber(3);
            mpp_f[8]->setConditionNumber(2);mpp_f[9]->setConditionNumber(2);
            break;

     default :
            for(int i=0;i<m_numFuncs;i++) mpp_f[i]->setConditionNumber(2.);
            break;
    }
}

int HybridComp::getNumFuncs(){
    return m_numFuncs;
}

bool HybridComp::loadTranslation(){
	string s;
	char a[100];
	sprintf(a,"%d",m_dimNumber);
	strcat(a,"Dim.txt");
	s=a;
	s.insert(0,gProName[m_id]+"_Opt_");

	s.insert(0,"Problems//FunctionOpt//Data//");//probDataPath
	ifstream in;
	in.open(s.c_str());

	if(in.fail()){
		switch(m_id){

		case RH_Com_CEC05: case RH_Com_NarrowBasin_CEC05:

			for(int i=0;i<m_numFuncs-1;i++)
			for(int j=0;j<m_dimNumber;j++){
				mpp_f[i]->getTranslation()[j]=((Boundary<double> *)m_searchRange[j])->lower +(((Boundary<double> *)m_searchRange[j])->upper-((Boundary<double> *)m_searchRange[j])->lower)*(1-Global::gp_uniformPro->Next());
			}

			for(int j=0;j<m_dimNumber;j++){
				mpp_f[m_numFuncs-1]->getTranslation()[j]=0;
			}

			break;
		case RH_Com_Bound_CEC05:

			for(int i=0;i<m_numFuncs-1;i++)
			for(int j=0;j<m_dimNumber;j++){
				if(i==0&&(j+1)%2==0) mpp_f[i]->getTranslation()[j]=((Boundary<double> *)m_searchRange[j])->upper;
				else mpp_f[i]->getTranslation()[j]=((Boundary<double> *)m_searchRange[j])->lower +(((Boundary<double> *)m_searchRange[j])->upper-((Boundary<double> *)m_searchRange[j])->lower)*(1-Global::gp_uniformPro->Next());
			}

			for(int j=0;j<m_dimNumber;j++){
				mpp_f[m_numFuncs-1]->getTranslation()[j]=0;
			}
			break;

          case RH_Com_noBounds_F25_CEC05:
               for(int j=0;j<m_dimNumber;j++){
				mpp_f[0]->getTranslation()[j]= -5.0 +(7.0)*(Global::gp_uniformPro->Next());
               }

			for(int i=1;i<m_numFuncs-1;i++)
			for(int j=0;j<m_dimNumber;j++){
				mpp_f[i]->getTranslation()[j]=((Boundary<double> *)m_searchRange[j])->lower +(((Boundary<double> *)m_searchRange[j])->upper-((Boundary<double> *)m_searchRange[j])->lower)*(1-Global::gp_uniformPro->Next());
			}

			for(int j=0;j<m_dimNumber;j++){
				mpp_f[m_numFuncs-1]->getTranslation()[j]=0;
			}
			break;

		default:
			for(int i=0;i<m_numFuncs;i++)
			for(int j=0;j<m_dimNumber;j++){
				mpp_f[i]->getTranslation()[j]=((Boundary<double> *)m_searchRange[j])->lower +(((Boundary<double> *)m_searchRange[j])->upper-((Boundary<double> *)m_searchRange[j])->lower)*(1-Global::gp_uniformPro->Next());
               }
			break;
		}

		ofstream out(s.c_str());
		for(int i=0;i<m_numFuncs;i++){
			for(int j=0;j<m_dimNumber;j++)
				out<<mpp_f[i]->getTranslation()[j]<<" ";
				out<<endl;
		}
		out.close();

	}else{
        for(int i=0;i<m_numFuncs;i++){
			for(int j=0;j<m_dimNumber;j++) {
				in>>mpp_f[i]->getTranslation()[j];
			}
		}
	}
	in.close();

    for(int i=0;i<m_numFuncs;i++)	mpp_f[i]->setTranlationFlag(true);

    return true;
}

bool HybridComp::loadRotation(){
    string s;
	char a[100];
	sprintf(a,"%d",m_dimNumber);
	strcat(a,"Dim.txt");
	s=a;
	s.insert(0,gProName[m_id]+"_RotM_");

	s.insert(0,"Problems//FunctionOpt//Data//");//probDataPath
	ifstream in;
	in.open(s.c_str());
	if(in.fail()){

		for(int i=0;i<m_numFuncs;i++){
			switch(m_id){
				case Com: case Com_CEC05:
                    mpp_f[i]->getRotation()->Identity();
					break;
				default:
					 mpp_f[i]->getRotation()->Randomize(false);
					mpp_f[i]->getRotation()->GenerateRotationMatrix(mpp_f[i]->getConditionNumber(),false);
					break;
			}
		}
		ofstream out(s.c_str());
		for(int i=0;i<m_numFuncs;i++) mpp_f[i]->getRotation()->Print(out);
		out.close();
	}else{
	    for(int i=0;i<m_numFuncs;i++)	mpp_f[i]->getRotation()->Read_Data(in);
	}

	for(int i=0;i<m_numFuncs;i++)	mpp_f[i]->setRotationFlag(true);
	in.close();
    return true;
}
void HybridComp::initialize(){

    setOriginalGlobalOpt();
    switch(m_id){
		case Com: case R_Com:
			setUpFCom();
			break;
		case Com_CEC05: case H_Com_CEC05: case H_Com_Noisy_CEC05:
			SetUpFCom_CEC05();
			break;
		case RH_Com_CEC05: case  RH_Com_NarrowBasin_CEC05: case RH_Com_Bound_CEC05:
			SetUpFRH_Com_CEC05();
			break;
		case RH_Com_F21_CEC05: case RH_Com_HighConNumMatrix_F22_CEC05: case Noncont_RH_Com_F23_CEC05:
               SetUpFRH001_Com_CEC05();
               break;
          case RH_Com_F24_CEC05:  case RH_Com_noBounds_F25_CEC05:
               SetUpFRH002_Com_CEC05();
               break;
		default:
            Throw(Invalid_argument("Error: please check the problem ID"));
            exit(0);
			break;
    }

    loadTranslation();
    loadRotation();

    double *x=new double [m_dimNumber];

    for(int i=0;i<m_numFuncs;i++){
        for(int j=0;j<m_dimNumber;j++){ // calculate the estimate max value of funciton i
            x[j]=((Boundary<double> *)m_searchRange[j])->upper;
            x[j]/=mp_stretchSeverity[i];
        }
        mp_fmax[i]=mpp_f[i]->BenchmarkFunction::evaluate(x,false);
     }
    delete [] x;

    setGlobalOpt();
    setAccuracy(1.0e-1);
}

void HybridComp::SetUpFRH002_Com_CEC05()
{
     char *fname[m_numFuncs];
    ProblemTag fid[m_numFuncs];
	for(int i=0;i<m_numFuncs;i++){
		mp_height[i]=100*i;
	}
	fid[0] = Weierstrass;
	fid[1] = Expanded_Scaffer_F6_CEC05;
	fid[2] = Griewank_Rosenbrock_F13_CEC05;
	fid[3] = Ackley;
	fid[4] = Rastrigin;
	fid[5] = Griewank;
	fid[6] = Noncont_Expanded_Scaffer_F6_CEC05;
	fid[7] = Noncont_Rastrigin;
	fid[8] = Elliptic;
	fid[9] = Sphere_Noisy_CEC05;

	mp_stretchSeverity[0]=10;
     mp_convergeSeverity[0]=2.;

    for(int i=0;i<m_numFuncs;i++)   fname[i]=const_cast<char *>(gProName[fid[i]].c_str());
    setFunction(fid,fname);

    mpp_f[0]->setSearchRange<double>(-0.5,0.5);
    mpp_f[1]->setSearchRange<double>(-100, 100);
	mpp_f[2]->setSearchRange<double>(-5,5);
	mpp_f[3]->setSearchRange<double>(-32,32);
	mpp_f[4]->setSearchRange<double>(-5,5);
	mpp_f[5]->setSearchRange<double>(-5,5);
    mpp_f[6]->setSearchRange<double>(-100, 100);
    mpp_f[7]->setSearchRange<double>(-5,5);
	mpp_f[8]->setSearchRange<double>(-100,100);
	mpp_f[9]->setSearchRange<double>(-100,100);

	mp_stretchSeverity[1]=5.0/20;
	mp_stretchSeverity[2]=1.0;
	mp_stretchSeverity[3]=5.0/32;
	mp_stretchSeverity[4]=1.0;
	mp_stretchSeverity[5]=5.0/100;
	mp_stretchSeverity[6]=5.0/50;
	mp_stretchSeverity[7]=1.0;
	mp_stretchSeverity[8]=5.0/100;
	mp_stretchSeverity[9]=5.0/100;

	mp_convergeSeverity[1]=2.;
	mp_convergeSeverity[2]=2.;	mp_convergeSeverity[3]=2.;
	mp_convergeSeverity[4]=2.;  mp_convergeSeverity[5]=2.;
	mp_convergeSeverity[6]=2;	mp_convergeSeverity[7]=2;
	mp_convergeSeverity[8]=2.;  mp_convergeSeverity[9]=2.;

    for(int i=0;i<m_numFuncs;i++){
		mpp_f[i]->setScale(mp_stretchSeverity[i]);
	}
	setBias(260);
}

void HybridComp::setUpFCom(){

	for(int i=0;i<m_numFuncs;i++){
		mp_height[i]=100*i;
		mp_convergeSeverity[i]=1.;
	}

	char *fname[m_numFuncs];
    ProblemTag fid[m_numFuncs];


	fid[0]=Sphere;		fid[1]=Sphere;
	fid[2]=Rastrigin;	fid[3]=Rastrigin;
	fid[4]=Weierstrass;	fid[5]=Weierstrass;
	fid[6]=Griewank;	fid[7]=Griewank;
	fid[8]=Ackley;		fid[9]=Ackley;

    for(int i=0;i<m_numFuncs;i++)  {
         fname[i]=const_cast<char *>(gProName[fid[i]].c_str());
    }

    setFunction(fid,fname);

	mpp_f[0]->setSearchRange<double>(-100,100); mpp_f[1]->setSearchRange<double>(-100,100);
	mpp_f[2]->setSearchRange<double>(-5,5);     mpp_f[3]->setSearchRange<double>(-5,5);
	mpp_f[4]->setSearchRange<double>(-0.5,0.5); mpp_f[5]->setSearchRange<double>(-0.5,0.5);
	mpp_f[6]->setSearchRange<double>(-100,100); mpp_f[7]->setSearchRange<double>(-100,100);
	mpp_f[8]->setSearchRange<double>(-32,32);   mpp_f[9]->setSearchRange<double>(-32,32);


	for(int i=0;i<m_numFuncs;i++){
		double l,u;
		mpp_f[i]->getSearchRange<double>(l,u,0);
		mp_stretchSeverity[i]=mp_convergeSeverity[i]*(((Boundary<double> *)m_searchRange[0])->upper-((Boundary<double> *)m_searchRange[0])->lower)/(u-l);
		mpp_f[i]->setScale(mp_stretchSeverity[i]);
	}
   // setBias(0);
}

void HybridComp::SetUpFRH001_Com_CEC05()
{
     char *fname[m_numFuncs];
    ProblemTag fid[m_numFuncs];
	for(int i=0;i<m_numFuncs;i++){
		mp_height[i]=100*i;
	}
	fid[0]=Expanded_Scaffer_F6_CEC05;		fid[1]=Expanded_Scaffer_F6_CEC05;
	fid[2]=Rastrigin;	fid[3]=Rastrigin;
	fid[4]=Griewank_Rosenbrock_F13_CEC05;		fid[5]=Griewank_Rosenbrock_F13_CEC05;
	fid[6]=Weierstrass;	fid[7]=Weierstrass;
	fid[8]=Griewank;		fid[9]=Griewank;

	mp_stretchSeverity[0]=5.*5./100;
     mp_convergeSeverity[0]=1.;

    for(int i=0;i<m_numFuncs;i++)   fname[i]=const_cast<char *>(gProName[fid[i]].c_str());
    setFunction(fid,fname);
    mpp_f[0]->setSearchRange<double>(-100,100);   mpp_f[1]->setSearchRange<double>(-100,100);
	mpp_f[2]->setSearchRange<double>(-5,5);     mpp_f[3]->setSearchRange<double>(-5,5);
	mpp_f[4]->setSearchRange<double>(-5,5); mpp_f[5]->setSearchRange<double>(-5,5);
    mpp_f[6]->setSearchRange<double>(-0.5,0.5); mpp_f[7]->setSearchRange<double>(-0.5,0.5);
	mpp_f[8]->setSearchRange<double>(-200,200); mpp_f[9]->setSearchRange<double>(-200,200);

	mp_stretchSeverity[1]=5./100;
	mp_stretchSeverity[2]=5.;		mp_stretchSeverity[3]=1.;
	mp_stretchSeverity[4]=5;  mp_stretchSeverity[5]=1;
	mp_stretchSeverity[6]=50.;	mp_stretchSeverity[7]=10.;
	mp_stretchSeverity[8]=5.*5/200;  mp_stretchSeverity[9]=5./200;

	mp_convergeSeverity[1]=1.;
	mp_convergeSeverity[2]=1.;	mp_convergeSeverity[3]=1.;
	mp_convergeSeverity[4]=1.;  mp_convergeSeverity[5]=2.;
	mp_convergeSeverity[6]=2;	mp_convergeSeverity[7]=2;
	mp_convergeSeverity[8]=2.;  mp_convergeSeverity[9]=2.;

    for(int i=0;i<m_numFuncs;i++){
		mpp_f[i]->setScale(mp_stretchSeverity[i]);
	}
	setBias(360);
}

void HybridComp::SetUpFCom_CEC05(){
	char *fname[m_numFuncs];
    ProblemTag fid[m_numFuncs];
	for(int i=0;i<m_numFuncs;i++){
		mp_height[i]=100*i;
		mp_convergeSeverity[i]=1.;
	}
	fid[0]=Rastrigin;	fid[1]=Rastrigin;
	fid[2]=Weierstrass;	fid[3]=Weierstrass;
	fid[4]=Griewank;	fid[5]=Griewank;
	fid[6]=Ackley;		fid[7]=Ackley;
	fid[8]=Sphere;		fid[9]=Sphere;

    for(int i=0;i<m_numFuncs;i++)   {
         fname[i]=const_cast<char *>(gProName[fid[i]].c_str());
    }
    setFunction(fid,fname);


	mpp_f[0]->setSearchRange<double>(-5,5);     mpp_f[1]->setSearchRange<double>(-5,5);
	mpp_f[2]->setSearchRange<double>(-0.5,0.5); mpp_f[3]->setSearchRange<double>(-0.5,0.5);
	mpp_f[4]->setSearchRange<double>(-60,60); mpp_f[5]->setSearchRange<double>(-60,60);
	mpp_f[6]->setSearchRange<double>(-32,32);   mpp_f[7]->setSearchRange<double>(-32,32);
	mpp_f[8]->setSearchRange<double>(-100,100); mpp_f[9]->setSearchRange<double>(-100,100);


	mp_stretchSeverity[0]=1.;		mp_stretchSeverity[1]=1.;
	mp_stretchSeverity[2]=10.;		mp_stretchSeverity[3]=10.;
	mp_stretchSeverity[4]=5./60;  mp_stretchSeverity[5]=5./60;
	mp_stretchSeverity[6]=5./32;	mp_stretchSeverity[7]=5./32;
	mp_stretchSeverity[8]=5./100;  mp_stretchSeverity[9]=5./100;

    for(int i=0;i<m_numFuncs;i++){
		mpp_f[i]->setScale(mp_stretchSeverity[i]);
	}

    setBias(120.);
}
void HybridComp::SetUpFRH_Com_CEC05(){
	char *fname[m_numFuncs];
    ProblemTag fid[m_numFuncs];
	for(int i=0;i<m_numFuncs;i++){
		mp_height[i]=100*i;

	}
	fid[0]=Ackley;		fid[1]=Ackley;
	fid[2]=Rastrigin;	fid[3]=Rastrigin;
	fid[4]=Sphere;		fid[5]=Sphere;
	fid[6]=Weierstrass;	fid[7]=Weierstrass;
	fid[8]=Griewank;		fid[9]=Griewank;

	if(m_id==RH_Com_NarrowBasin_CEC05)   {
	    mp_stretchSeverity[0]=0.1*5./32;
		mp_convergeSeverity[0]=0.1;
	}else{
        mp_stretchSeverity[0]=2.*5./32;
		mp_convergeSeverity[0]=1.;
	}
    for(int i=0;i<m_numFuncs;i++)   fname[i]=const_cast<char *>(gProName[fid[i]].c_str());
    setFunction(fid,fname);


    mpp_f[0]->setSearchRange<double>(-32,32);   mpp_f[1]->setSearchRange<double>(-32,32);
	mpp_f[2]->setSearchRange<double>(-5,5);     mpp_f[3]->setSearchRange<double>(-5,5);
	mpp_f[4]->setSearchRange<double>(-100,100); mpp_f[5]->setSearchRange<double>(-100,100);
    mpp_f[6]->setSearchRange<double>(-0.5,0.5); mpp_f[7]->setSearchRange<double>(-0.5,0.5);
	mpp_f[8]->setSearchRange<double>(-60,60); mpp_f[9]->setSearchRange<double>(-60,60);


	mp_stretchSeverity[1]=5./32;
	mp_stretchSeverity[2]=2.;		mp_stretchSeverity[3]=1.;
	mp_stretchSeverity[4]=2*5./100;  mp_stretchSeverity[5]=5./100;
	mp_stretchSeverity[6]=20.;	mp_stretchSeverity[7]=10.;
	mp_stretchSeverity[8]=2.*5/60;  mp_stretchSeverity[9]=5./60;

	mp_convergeSeverity[1]=2.;
	mp_convergeSeverity[2]=1.5;	mp_convergeSeverity[3]=1.5;
	mp_convergeSeverity[4]=1.;  mp_convergeSeverity[5]=1.;
	mp_convergeSeverity[6]=1.5;	mp_convergeSeverity[7]=1.5;
	mp_convergeSeverity[8]=2.;  mp_convergeSeverity[9]=2.;

    for(int i=0;i<m_numFuncs;i++){
		mpp_f[i]->setScale(mp_stretchSeverity[i]);
	}
	setBias(10.);
}

 double HybridComp::evaluate_(double  const *x){
     double * x_ = new double[m_dimNumber];
      if(m_id == Noncont_RH_Com_F23_CEC05) {
           for(int j=0; j<m_dimNumber; ++j) {
               double trans = mpp_f[0]->getTranslation()[j];
               if(fabs(x[j] - trans) >= 0.5) {
                    double xTemp = 2.0 * x[j];
                    int intPart = int(xTemp);
                    double decimalPart = xTemp - intPart;
                    if(xTemp <= 0 && decimalPart >= 0.5) xTemp = intPart - 1;
                    else if(decimalPart < 0.5) xTemp = intPart;
                    else xTemp = intPart + 1;
                    x_[j] = xTemp / 2.0;
               }
               else x_[j] = x[j];
           }
      }
      else gCopy(x_,x,m_dimNumber);

	for(int i=0;i<m_numFuncs;i++){ // calculate mp_weight for each function
		mp_weight[i]=0;
		for(int j=0;j<m_dimNumber;j++) {
			mp_weight[i]+=(x_[j]-mpp_f[i]->getTranslation()[j])*(x_[j]-mpp_f[i]->getTranslation()[j]);
		}
		mp_weight[i]=exp(-sqrt(mp_weight[i]/(2*m_dimNumber*mp_convergeSeverity[i]*mp_convergeSeverity[i])));
	}

	for(int i=0;i<m_numFuncs;i++){ // calculate objective value for each function
		mp_fit[i]=mpp_f[i]->BenchmarkFunction::evaluate(x_,false);
		if(mp_fmax[i]!=0)
		mp_fit[i]=m_heightNormalizeSeverity*mp_fit[i]/fabs(mp_fmax[i]);
	}

	double sumw=0,wmax;
	wmax=gExtremum(mp_weight,m_numFuncs,MAX_OPT);
	for(int i=0;i<m_numFuncs;i++) {
		if(mp_weight[i]!=wmax) {
			mp_weight[i]=mp_weight[i]*(1-pow(wmax,10));
		}
	}
     int sameWmax_N = 0;
     for(int i=0; i<m_numFuncs; ++i) {
          if(mp_weight[i] == wmax) ++sameWmax_N;
     }
     int i=m_numFuncs-1;
     while(sameWmax_N > 1 && i >= 0) {
          if(wmax == mp_weight[i]) {
               mp_weight[i] = 0;
               --sameWmax_N;
          }
          --i;
     }

	for(int i=0;i<m_numFuncs;i++)
		sumw+=mp_weight[i];
	for(int i=0;i<m_numFuncs;i++)
		mp_weight[i]/=sumw;

	double obj=0;
	for(int i=0;i<m_numFuncs;i++) {
		obj+=mp_weight[i]*(mp_fit[i]+mp_height[i]);
	}

	delete[] x_;

	if(m_id ==H_Com_Noisy_CEC05) return obj*(1+0.2*fabs(Global::gp_normalPro->Next()))+m_bias;
	else	return obj+m_bias;

 }
void HybridComp::setGlobalOpt(){
    m_globalOpt.m_knownFlag=true;
    gCopy(m_globalOpt.mp_location,mpp_f[0]->getTranslation(),m_dimNumber);
    m_globalOpt.m_value=BenchmarkFunction::evaluate(m_globalOpt.mp_location,false);
    m_originalGlobalOpt.m_knownFlag=false;
}

void HybridComp::setOriginalGlobalOpt(){
    m_originalGlobalOpt.m_knownFlag=false;
}
