/*************************************************************************
* 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.
*************************************************************************/
/*
J. Branke, Memory enhanced evolutionary algorithms for changing optimization
problems, Proc. of the 1999 Congr. on Evol. Comput, pp. 1875-1882, 1999.
*/
// Created: 11 May 2011
// Last modified:
#ifndef MOVINGPEAK_H
#define MOVINGPEAK_H

#include "DynamicContinuous.h"

class MovingPeak : public DynamicContinuous
{
private:
    int m_F;
    double m_vlength ; /* distance by which the peaks are moved, severity */

    /* lambda determines whether there is a direction of the movement, or whether
    they are totally random. For lambda = 1.0 each move has the same direction,
    while for lambda = 0.0, each move has a random direction */
    double m_lambda;
    int m_useBasisFunction; /* if set to 1, a   landscape (basis_function) is included in the fitness evaluation */
    int m_calculateRightPeak ; /* saves computation time if not needed and set to 0 */
    double  m_standardHeight;
    /* width chosen randomly when standardwidth = 0.0 */
    double  m_standardWidth;

    double *mp_shift;
    int *mp_coveredPeaks;    /* which peaks are covered by the population ? */
    double **mpp_prevMovement;/* to store every peak's previous movement */
	int *mp_isTracked;     
	int *mp_heightOrder;
	bool *mp_found; 
	int m_peaksFound;
private:
    MovingPeak(const int rId, const int rDimNumber, const Encoding rEncoding, const int rNumPeaks, float const rChangingRatio,const bool rFlagDimChange=false,const bool rFlagNumPeakChange=false);
    bool readData();
    static  MovingPeak *msp_MPs;
    /* the following basis functions are provided :*/
    double constantBasisFunc(double *gen);
    double fivePeakBasisFunc(double *gen);
    /* the following peak functions are provided: */
    double peakFunction1(double *gen, int peak_number);
    double peakFunctionCone (double *gen, int peak_number);
    double peakFunctionHilly (double *gen, int peak_number);
    double peakFunctionTwin (double  *gen, int peak_number);
    double functionSelection(double  *gen, int peak_number);
    double dummyEval (double *gen);
    void initialize();

protected:
    void currentPeakCalc (double *gen);
    virtual void  freeMemory();
    virtual void allocateMemory(const int rDimNum, const int rPeaks);
    virtual void randomChange();
    ///TODO the flowing change types are not implemented
    virtual void smallStepChange(){randomChange();};
    virtual void largeStepChange(){randomChange();};
    virtual void recurrentChange(){randomChange();};
    virtual void chaoticChange(){randomChange();};
    virtual void recurrentNoisyChange(){randomChange();};
    virtual void changeDimension(){randomChange();};
    virtual void changeNumPeaks();
	void parameterSetting(DynamicProblem * rP);


public:
    static  MovingPeak * getMPs();
    static void initialize(int rDim, int rPeaks,float const rChangingRatio, const bool rFlagDimChange=false,const bool flagNumPeakChange=false);
    static void deleteMPs();
    static bool isInitialized();
    virtual ~MovingPeak();

    virtual double evaluate (double const *gen, bool rFlag=true);
    void changeStepsizeRandom () ;
    void changeStepsizeLinear();
    int getRightPeak();
    void setVlength(const double s);
    void reset();
	MovingPeak &operator=(MovingPeak &other);
	int getTrackNumber(int idex);
	bool isTracked(double const *gen);
	int getPeaksFound();
};

#endif // MOVINGPEAK_H
