/*
 * MultimodalAlgorithm.h
 *
 *  Created on: Jul 28, 2015
 *      Author: jjpalacios
 */

#ifndef SRC_ECMETHODS_MULTIMODALALGORITHM_H_
#define SRC_ECMETHODS_MULTIMODALALGORITHM_H_


#include "../heading.h"
#include "../ClassRegister.h"
#include "../ecObjects/SharedVars.h"
#include "../ecObjects/Population.h"
#include "../ecObjects/Evaluation.h"


namespace clbDEB {

// Results object
typedef Population Results;
typedef Individual Solution;


// Parameters defined in this header file
#define MMA_FITNESS_MAX "fitness-maximize"	// Indicates if the fitness is to be maximized
#define MMA_INDIVIDUAL_LENGTH "genome-length"	// Number of genes per individual
#define MMA_BOUNDS_MIN "gene-min."	// gene-min.x: Minimum value for parameter x
#define MMA_BOUNDS_MAX "gene-max."	// gene-min.x: Minimum value for parameter x
#define EVAL_FUNCTION "evaluator"	// Name of the evaluation function



//=============================================================================
//
//	Abstract class MultimodalAlgorithm
//
//=============================================================================
/**
 * This class provides the framework to implement any kind of multimodal
 * evolutionary algorithm.
 *
 * @author jjpalacios
 *
 */
class MultimodalAlgorithm {
	//=========================================================================
	//		COMMON FIELDS
	//=========================================================================
protected:
	/**
	 * Indicates if the algorithm is ready to run
	 */
	bool ready;

public:
	/**
	 * Shared variables for the algorithm
	 */
	SharedVars * sharedVariables;

	/**
	 * Evaluation function to use
	 */
	Evaluation * evaluator;

	/**
	 * Flag indicating the status of the algorithm
	 */
	bool finished;



	//=========================================================================
	//		CONSTRUCTORS / INITIALIZERS
	//=========================================================================
public:
	/**
	 * Constructor using the parameters file.
	 * Reads the parameters file, but does not initialize objects
	 */
	explicit MultimodalAlgorithm(const char * setupFile);

	/**
	 * Destructor
	 */
	virtual ~MultimodalAlgorithm() {
		delete sharedVariables;
		delete evaluator;
	}

protected:
	/**
	 * Destroys everything
	 */
	virtual void clearAll();



	//=========================================================================
	//		GET/SET METHODS
	//=========================================================================
public:
	/**
	 * This method prints the configuration of the algorithm in CSV format
	 * and using a tree structure for a better understanding
	 *
	 * @return A string of parameter values. The first string is the name of
	 * the operator
	 */
	virtual void printSetupTree(std::ofstream & output) const=0;


	/**
	 * Returns the basic statistics provided by the algorithm
	 *
	 * @return An array of pairs with the name of the statistic and its value
	 */
	virtual std::vector< std::pair<std::string, double> > getStatistics() const=0;

	/**
	 * Returns the time employed by each component of the algorithm
	 *
	 * @return An array of pairs with the name of the component and the time
	 * consumed. The first component is always the total runtime, the others
	 * are relative to the total amount of time
	 */
	virtual std::vector< std::pair<std::string, double> > getRuntime() const=0;

	/**
	 * Returns the evolution of the algorithm during the run
	 *
	 * @param labels Output variable to store the name of each evolution
	 * component
	 * @return A matrix with the evolution of different elements
	 */
	virtual std::vector< std::vector<double> > getEvolution(
			std::vector< std::string > &labels) const=0;



	//=========================================================================
	//		METHODS
	//=========================================================================
public:
	/**
	 * Creates all the objects that are needed by the algorithm from the
	 * configuration stored in the ParameterDB object. This must be called
	 * the first time we want to run the algorithm. If a parameter is changed
	 * between the runs, it must be called again
	 */
	virtual void prepareToRun();


	/**
	 * Run the algorithm
	 *
	 * @return A set of solutions
	 */
	virtual Results * run(std::string signature, std::string logFolder,
				int rngSeed)=0;

};


}

#endif /* SRC_ECMETHODS_MULTIMODALALGORITHM_H_ */
