#ifndef STRCUTDEC_H_INCLUDED
#define STRCUTDEC_H_INCLUDED

#include<iostream>
using namespace std;

/*************************************************************************
* 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:
// struct and macro declaration

// types of problems
/*#define PRO_STATIC      0X01
#define PRO_DYNAMIC     0x02
#define PRO_MULTI_OBJ   0x04
#define PRO_CONSTRAINT  0x08
*/


#define MAX_NAME_LENGTH 250

#define PI acos(-1.0) ///3.14159265358979323846
#define E exp(1.0)  // 2.71828182845904523536

enum Compare{MIN_OPT=0,MAX_OPT};

enum Encoding{C_DECIMAL=0, C_BINARY, C_INTEGER, C_STRING, C_UNSER_DEFINED};

enum ProCategory{CAT_STATIC,CAT_DYNAMIC,CAT_MULTIOBJ,CAT_CONSTRAINT};


/// TODO, the boundary class is not generic, only support problems in continuous space

template<typename T>
struct Boundary{						//***************************************************//
T upper;							//Dimension boudary in the landscape
T lower;							//**************************************************//
Encoding m_coding;
bool m_flag;                        // flag of rigid boundary
Boundary():m_coding(C_DECIMAL),m_flag(true){};
Boundary(bool flag):m_coding(C_DECIMAL),m_flag(flag){};
void setBoundary(const T rLower, const T rUpper){
    lower=rLower;
    upper=rUpper;
};

Boundary & operator=(const Boundary<T> &rBound){
    if(this==&rBound) return *this;
    upper=rBound.upper;
    lower=rBound.lower;
    return *this;
};
};

//***********************Enviroment change types in GDBG system ******************************//
enum ChangeType{CT_SmallStep=0, CT_LargeStep,CT_Random,CT_Recurrent,CT_Chaotic,CT_RecurrentNoisy};

struct SChangeType{
	ChangeType type;
	int counter;
	SChangeType & operator=(const SChangeType & rCT){
	    if(this==&rCT)  return *this;
        type=rCT.type;
        counter=rCT.counter;
        return *this;
	};
};

enum ProblemTag{
//Benchmark problems
Sphere=0,Sphere_Noisy,S_Sphere,R_Sphere,RS_Sphere,S_Sphere_CEC05, Sphere_Noisy_CEC05
,Rastrigin,Rastrigin_Noisy,S_Rastrigin,R_Rastrigin,RS_Rastrigin,S_Rastrigin_CEC05,RS_Rastrigin_CEC05
,Weierstrass,RS_Weierstrass,R_Weierstrass,RS_Weierstrass_CEC05
,Griewank,R_Griewank,RS_Griewank, RS_Griewank_noBounds_CEC05, Griewank_Rosenbrock_F13_CEC05, S_Griewank_Rosenbrock_F13_CEC05
,Ackley,Ackley_Noisy,S_Ackley,R_Ackley,RS_Ackley,RS_Ackley_Bound_CEC05
,Step
,Quartic_Noisy
,Scaffer_F6, Expanded_Scaffer_F6_CEC05, Noncont_Expanded_Scaffer_F6_CEC05, RS_Expanded_Scaffer_F6_CEC05
,Rosenbrock,S_Rosenbrock,S_Rosenbrock_CEC05
,Schwefel_2_13_CEC05
,Schwefel_2_22,Schwefel_2_22_Noisy,S_Schwefel_2_22,R_Schwefel_2_22,RS_Schwefel_2_22
,Schwefel,Schwefel_Noisy,S_Schwefel,R_Schwefel,RS_Schwefel
,Schwefel_1_2,Schwefel_1_2_Noisy,S_Schwefel_1_2,S_Schwefel_1_2_Noisy,R_Schwefel_1_2,RS_Schwefel_1_2, S_Schwefel_1_2_CEC05, S_Schwefel_1_2_Noisy_CEC05
,Schwefel_2_21
,Schwefel_2_6_Bound_CEC05
,Penalized_1
,Penalized_2
,Noncont_Rastrigin
,RS_Elliptic_CEC05,Elliptic
,Com,R_Com,Com_CEC05,H_Com_CEC05,H_Com_Noisy_CEC05
,RH_Com_CEC05,RH_Com_NarrowBasin_CEC05,RH_Com_Bound_CEC05
,RH_Com_F21_CEC05, RH_Com_HighConNumMatrix_F22_CEC05, Noncont_RH_Com_F23_CEC05, RH_Com_F24_CEC05, RH_Com_noBounds_F25_CEC05
,M_global1,M_global2,M_global3,M_global4,M_global5
,S_Sphere_CEC08,Schwefel_2_21_CEC08,S_Rosenbrock_CEC08,S_Rastrigin_CEC08,S_Griewank_CEC08,S_Ackley_CEC08
//,Inverted_Shubert,Langermann

///real-world problems
,RW_Gear_Train,RW_ParEst_FMSoundWaves

///Dynamic Problems
,CompositionDBG_DOP,RotationDBG_DOP,MovingPeak_DOP,DF1_DOP,Binary_DOP
};
enum AlgorithmTag{
    //PSO
    ALG_SPSO=0,ALG_SPSO07,ALG_SLPSO,ALG_APSO,ALG_CPSOH,
    //DE
    ALG_SDE,ALG_CRDE,
    //GA
   ALG_SGA_REAL,
    //dynamic optimization
    ALG_CPSO, ALG_CPSOR,ALG_CDER,ALG_ESCA, ALG_SPSO_Parrott,ALG_rSPSO,ALG_mCPSO,ALG_mQSO,ALG_PSO_CP,ALG_HmSO,ALG_SOS,ALG_DynDE,
    ALG_CPSORL,ALG_CPSORC,ALG_mPSO,ALG_mDE,ALG_CPSOD,
    //DE
    ALG_Ming_DE, ALG_SaPDE, ALG_JADE, ALG_jDE, ALG_SaDE, ALG_dynNPDE, ALG_cDE,
    //CMAES
    ALG_CMAES,
    ALG_CLPSO,
    ALG_HRCGA
};




struct Gene{
unsigned int m_length;
Encoding  m_coding;
void *mp_value;
};

enum PopInitMethod{POP_INIT_UNIFORM=0,POP_INIT_ORTHONORM,POP_INIT_CENTER,POP_INIT_USER_DEFINED};

enum ConvgProgeMode{PROGR_MEAN=0, PROGR_MEDEAN,PROGR_WORST, PROGR_BEST};
// the mode of the convergence speed graph,e.g., PROGR_MEAN denotes the mean value of all runs

enum SolutionValidation{VALIDATION_IGNORE=0,VALIDATION_REINITIALIZE,VALIDATION_REMAP,VALIDATION_SETTOBOUND};
//means of handling a solution that is out of the search space in continuous space

enum GAMutationStrategy{MUTAT_POLYNOMIAL,MUTAT_NORMAL};
enum GASelectionStrategy{SEL_TOURNAMENT=0,SEL_ROULETTE_WHEEL};

enum DEMutationStratgy{DE_rand_1, DE_best_1,DE_targetToBest_1,DE_best_2,DE_rand_2,DE_randToBest_1,DE_targetToRand_1};
enum DistanceMode{DIS_EUCLIDEAN=0,DIS_MANHATTAN,DIS_HAMMING};

enum MigrationMode{Migration_Best=0,Migration_Worst,Migration_Random};
enum MigrationTopology{Migration_Ring=0,Migration_Broadcast};

#endif // STRCUTDEC_H_INCLUDED
