/*************************************************************************
* 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 July 2011
// Last modified:

// dynamic binary problem with multiple peaks
#ifndef BINARYDOP_H
#define BINARYDOP_H

#include "DynamicProblem.h"


class BinaryDOP : public DynamicProblem
{
private:								//************************Dynamic Benchmark Generator for Binary**************//
	bool ** mpp_peak;						    //locations of peaks
	bool **mpp_prePeak;
	double *mp_height;                  //in [0,1]
	double *mp_preHeight;

	int m_length;

	static BinaryDOP *msp_binaryDOP;		//only single instance of BinaryDOP class
	double *mp_initialAngle;				    //initial phase of sin fucntion in recurrent or recurrent_noisy change
    float m_heightSeverity;

    double m_globalOptima;				    	// global optima value
    bool *mp_globalOptimaIdx;                      // the index of the global optimal peak
    int m_maxPeaksNumber;                      // the number of heigthest peaks

private:
	BinaryDOP(const int rId, const int rDimNumber,const int rNumPeaks, const int rLength,const ChangeType rT,const Encoding rEncoding=C_BINARY);
public:
	virtual ~BinaryDOP();
	 static  BinaryDOP * getBinaryDOP();
	 static void deleteBinaryDOP();

	virtual double evaluate(const bool   *, bool rFlag=true);

    static void initialize( int rPeaks,int rLength, const ChangeType rT);
    static bool isInitialized();
    void setHeightSeverity(const float rS){
        m_heightSeverity=rS;
    };

    double getGlobalMax()const;

    const bool * const getPeak(const int p) const;
    const bool * const* const getAllPeaks()const;
    double getPeakHeight(const int p)const;
    double getPrePeakHeight(const int p)const;
    const double *const getHeight() const;

    const bool *const getPrePeak(const int p)const;
    const bool *const getGlobalOptimaIdx()const;
    int getNumberofGlobalOptPeak()const;
    BinaryDOP &operator=(const BinaryDOP &rBDOP);

    int getLength();
    void setHeight(const double *h);
    void setPosition(const bool * const * const p);//const double **p
    void printPeak( const int rIdx);

    //static const int msc_NumChangeTypies=6;

    virtual bool getObjGlobalOpt(double *, int rNumObj=1);
    void reset();

protected:													// six dynamic changes types
	virtual void randomChange();
    virtual void smallStepChange();
    virtual void largeStepChange();
    virtual void recurrentChange();
    virtual void chaoticChange();
    virtual void recurrentNoisyChange();


	void standardChange(int num_ones,int step, int );

	// dimension changes(linear inrease or decrease)
	virtual void changeDimension(){};
    virtual void changeNumPeaks(){};

    virtual void allocateMemory(int rPeaks, int rLength);
	virtual void  freeMemory();
	int HammingDistance(bool *source, bool * destination);
	void calculateInitialAngle();
	void calculateGlobalOptima();


};

#endif // BINARYDOP_H
