/*************************************************************************
* 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:
/// declaration of dynamic problems

#ifndef DYNAMICPROBLEM_H
#define DYNAMICPROBLEM_H

#include "../Problem.h"


class DynamicProblem : public Problem
{
    protected:

        int m_changeFre;
        SChangeType m_changeType;

        int m_period;					// definite period for values repeating
        int m_changeCounter;				// counter of number of changes
        float m_noisySeverity;		// deviation servity from the trajactory of recurrent change
        bool m_flagDimensionChange;			// flag=true, the number of dimensions change, otherwise no change,  default value is false
        bool m_dirDimensionChange;			// direction of change, dir=true means increasing the dimension, otherwise decrease it
        bool m_synchronize;                 // default=true all dimensions change at the same time

        int m_dimNumberTemp;                //a temporal variable for dimensional change only

        int m_numPeaks;
        bool m_flagNumPeaksChange;                  // flag of the change of the number of peaks
        bool m_dirNumPeaksChange;                   // true for increasing the number of peaks, otherwise decreasing the number of peaks
        int m_numPeaksTemp;                         // temporal varibal for number of peaks change only


        static const unsigned int msc_MaxDimensionNumber=15;
        static const unsigned int msc_MinDimensionNumber=2;     //should be greater than 1
        static const unsigned int msc_MaxNumPeaks=50;
        static const unsigned int msc_MinNumPeaks=10;

        float m_alpha, m_maxAlpha;              // to control step severity
        float m_chaoticConstant;
        int m_maxChangeNumber;                  // the number of the maximum changes during one run

        void setDimensionChange(const bool rFlag);
        void setChangeDirction(const bool rFlag);

    public:
        static int msc_NumChangeTypies;


        DynamicProblem(const int rId, const int rDimNumber, const Encoding rEncoding,const int rNumPeaks);
        virtual ~DynamicProblem()=0;

        DynamicProblem & operator=(const DynamicProblem & rDP);

        void setChangeFre(const int rChangeFre);
        virtual bool setPeriod(const int rPeriod);
        void setChangeType(const SChangeType &rChangeType);
        void setChangeType(const ChangeType rT);
				void setNumPeaksChange(const bool rPC);
        void setSynchronize(const bool rFlag);
        void setNoisySeverity(const float rSeverity);
        void setMaxChangeNumber(const int rMaxChangeNum);
        void setAlpha(const float rAlpha){
            m_alpha=rAlpha;
        };
        void setMaxAlpha(const float rMaxAlpha){
            m_maxAlpha=rMaxAlpha;
        };
        void setChoaticConstant(const float rValue){
            m_chaoticConstant=rValue;
        }

        int getChangeFre()const{
            return m_changeFre;
        };
         int getChangeCounter()const {
            return m_changeCounter;
        };
        int getPeriod()const {
            return m_period;
        }
         ChangeType getChangeType() const{
            return m_changeType.type;
        };
         bool getFlagDimensionChange() const{
            return m_flagDimensionChange;
        };
         bool getDirDimensionChange() const{
            return m_dirDimensionChange;
        };
         bool getFlagSynchronizeChange()const{
            return m_synchronize;
        };
        int getMaxChangeNumber()const{
            return m_maxChangeNumber;
        };
		
        int getNumberofPeak()const;

        void change();
        double sinValueNoisy(const int x,const double min, const double max, const double amplitude, const double angle,const double noisy_severity=1.);
        double chaoticStep(const double x, const double min, const double max, const float scale=1.0);
		bool predictChange(const int evalsMore);
    protected:
        virtual void randomChange(){};
        virtual void smallStepChange(){};
        virtual void largeStepChange(){};
        virtual void recurrentChange(){};
        virtual void chaoticChange(){};
        virtual void recurrentNoisyChange(){};

        virtual void changeDimension(){};
        virtual void changeNumPeaks(){};


        virtual void parameterSetting(Problem * rP);
        virtual void  freeMemory(){};
};

#endif // DYNAMICPROBLEM_H
